Skip to content

Commit 01f418c

Browse files
Move test_deserialize_empty_collections to cql_types.rs
1 parent 2e1e192 commit 01f418c

File tree

2 files changed

+68
-68
lines changed

2 files changed

+68
-68
lines changed

scylla/tests/integration/cql_types.rs

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ use scylla::serialize::value::SerializeValue;
44
use scylla::value::{Counter, CqlDate, CqlTime, CqlTimestamp, CqlTimeuuid, CqlValue, CqlVarint};
55
use scylla::{DeserializeValue, SerializeValue};
66
use std::cmp::PartialEq;
7+
use std::collections::{HashMap, HashSet};
78
use std::fmt::Debug;
89
use std::net::{IpAddr, Ipv4Addr, Ipv6Addr};
910
use std::str::FromStr;
@@ -1863,3 +1864,67 @@ async fn test_udt_with_missing_field() {
18631864
)
18641865
.await;
18651866
}
1867+
1868+
/// ScyllaDB does not distinguish empty collections from nulls. That is, INSERTing an empty collection
1869+
/// is equivalent to nullifying the corresponding column.
1870+
/// As pointed out in [#1001](https://github.com/scylladb/scylla-rust-driver/issues/1001), it's a nice
1871+
/// QOL feature to be able to deserialize empty CQL collections to empty Rust collections instead of
1872+
/// `None::<RustCollection>`. This test checks that.
1873+
#[tokio::test]
1874+
async fn test_deserialize_empty_collections() {
1875+
// Setup session.
1876+
let ks = unique_keyspace_name();
1877+
let session = create_new_session_builder().build().await.unwrap();
1878+
session.ddl(format!("CREATE KEYSPACE IF NOT EXISTS {} WITH REPLICATION = {{'class' : 'NetworkTopologyStrategy', 'replication_factor' : 1}}", ks)).await.unwrap();
1879+
session.use_keyspace(&ks, true).await.unwrap();
1880+
1881+
async fn deserialize_empty_collection<
1882+
Collection: Default + DeserializeOwnedValue + SerializeValue,
1883+
>(
1884+
session: &Session,
1885+
collection_name: &str,
1886+
collection_type_params: &str,
1887+
) -> Collection {
1888+
// Create a table for the given collection type.
1889+
let table_name = "test_empty_".to_owned() + collection_name;
1890+
let query = format!(
1891+
"CREATE TABLE {} (n int primary key, c {}<{}>)",
1892+
table_name, collection_name, collection_type_params
1893+
);
1894+
session.ddl(query).await.unwrap();
1895+
1896+
// Populate the table with an empty collection, effectively inserting null as the collection.
1897+
session
1898+
.query_unpaged(
1899+
format!("INSERT INTO {} (n, c) VALUES (?, ?)", table_name,),
1900+
(0, Collection::default()),
1901+
)
1902+
.await
1903+
.unwrap();
1904+
1905+
let query_rows_result = session
1906+
.query_unpaged(format!("SELECT c FROM {}", table_name), ())
1907+
.await
1908+
.unwrap()
1909+
.into_rows_result()
1910+
.unwrap();
1911+
let (collection,) = query_rows_result.first_row::<(Collection,)>().unwrap();
1912+
1913+
// Drop the table
1914+
collection
1915+
}
1916+
1917+
let list = deserialize_empty_collection::<Vec<i32>>(&session, "list", "int").await;
1918+
assert!(list.is_empty());
1919+
1920+
let set = deserialize_empty_collection::<HashSet<i64>>(&session, "set", "bigint").await;
1921+
assert!(set.is_empty());
1922+
1923+
let map = deserialize_empty_collection::<HashMap<bool, CqlVarint>>(
1924+
&session,
1925+
"map",
1926+
"boolean, varint",
1927+
)
1928+
.await;
1929+
assert!(map.is_empty());
1930+
}

scylla/tests/integration/session.rs

Lines changed: 3 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use crate::utils::{
22
create_new_session_builder, scylla_supports_tablets, setup_tracing, supports_feature,
3-
unique_keyspace_name, DeserializeOwnedValue, PerformDDL,
3+
unique_keyspace_name, PerformDDL,
44
};
55
use assert_matches::assert_matches;
66
use futures::{FutureExt, StreamExt as _, TryStreamExt};
@@ -25,10 +25,9 @@ use scylla::routing::partitioner::{calculate_token_for_partition_key, Partitione
2525
use scylla::statement::Consistency;
2626
use scylla_cql::frame::request::query::{PagingState, PagingStateResponse};
2727
use scylla_cql::serialize::row::{SerializeRow, SerializedValues};
28-
use scylla_cql::serialize::value::SerializeValue;
29-
use scylla_cql::value::{CqlVarint, Row};
28+
use scylla_cql::value::Row;
29+
use std::collections::BTreeSet;
3030
use std::collections::HashMap;
31-
use std::collections::{BTreeSet, HashSet};
3231
use std::sync::atomic::{AtomicBool, Ordering};
3332
use std::sync::Arc;
3433
use tokio::net::TcpListener;
@@ -2530,70 +2529,6 @@ async fn test_manual_primary_key_computation() {
25302529
}
25312530
}
25322531

2533-
/// ScyllaDB does not distinguish empty collections from nulls. That is, INSERTing an empty collection
2534-
/// is equivalent to nullifying the corresponding column.
2535-
/// As pointed out in [#1001](https://github.com/scylladb/scylla-rust-driver/issues/1001), it's a nice
2536-
/// QOL feature to be able to deserialize empty CQL collections to empty Rust collections instead of
2537-
/// `None::<RustCollection>`. This test checks that.
2538-
#[tokio::test]
2539-
async fn test_deserialize_empty_collections() {
2540-
// Setup session.
2541-
let ks = unique_keyspace_name();
2542-
let session = create_new_session_builder().build().await.unwrap();
2543-
session.ddl(format!("CREATE KEYSPACE IF NOT EXISTS {} WITH REPLICATION = {{'class' : 'NetworkTopologyStrategy', 'replication_factor' : 1}}", ks)).await.unwrap();
2544-
session.use_keyspace(&ks, true).await.unwrap();
2545-
2546-
async fn deserialize_empty_collection<
2547-
Collection: Default + DeserializeOwnedValue + SerializeValue,
2548-
>(
2549-
session: &Session,
2550-
collection_name: &str,
2551-
collection_type_params: &str,
2552-
) -> Collection {
2553-
// Create a table for the given collection type.
2554-
let table_name = "test_empty_".to_owned() + collection_name;
2555-
let query = format!(
2556-
"CREATE TABLE {} (n int primary key, c {}<{}>)",
2557-
table_name, collection_name, collection_type_params
2558-
);
2559-
session.ddl(query).await.unwrap();
2560-
2561-
// Populate the table with an empty collection, effectively inserting null as the collection.
2562-
session
2563-
.query_unpaged(
2564-
format!("INSERT INTO {} (n, c) VALUES (?, ?)", table_name,),
2565-
(0, Collection::default()),
2566-
)
2567-
.await
2568-
.unwrap();
2569-
2570-
let query_rows_result = session
2571-
.query_unpaged(format!("SELECT c FROM {}", table_name), ())
2572-
.await
2573-
.unwrap()
2574-
.into_rows_result()
2575-
.unwrap();
2576-
let (collection,) = query_rows_result.first_row::<(Collection,)>().unwrap();
2577-
2578-
// Drop the table
2579-
collection
2580-
}
2581-
2582-
let list = deserialize_empty_collection::<Vec<i32>>(&session, "list", "int").await;
2583-
assert!(list.is_empty());
2584-
2585-
let set = deserialize_empty_collection::<HashSet<i64>>(&session, "set", "bigint").await;
2586-
assert!(set.is_empty());
2587-
2588-
let map = deserialize_empty_collection::<HashMap<bool, CqlVarint>>(
2589-
&session,
2590-
"map",
2591-
"boolean, varint",
2592-
)
2593-
.await;
2594-
assert!(map.is_empty());
2595-
}
2596-
25972532
#[cfg(cassandra_tests)]
25982533
#[tokio::test]
25992534
async fn test_vector_type_metadata() {

0 commit comments

Comments
 (0)