Skip to content

Commit 1621a93

Browse files
committed
Metadata: Verify that there are no gaps in pk and ck
Previously it was possible that some positions of `partition_key` and `clustering_key` would remain unfilled and thus empty strings. The probability was very low - Scylla would have to return very weird data - but the possibility was there. This commit verifies that this is not happening, and returns and error if it is.
1 parent 1b1fefd commit 1621a93

File tree

1 file changed

+39
-8
lines changed

1 file changed

+39
-8
lines changed

scylla/src/cluster/metadata.rs

Lines changed: 39 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,10 @@ type PerKsTableResult<T, E> = PerKsTable<Result<T, E>>;
7777
pub(crate) enum SingleKeyspaceMetadataError {
7878
#[error(transparent)]
7979
MissingUDT(MissingUserDefinedType),
80+
#[error("Partition key column with position {0} is missing from metadata")]
81+
IncompletePartitionKey(i32),
82+
#[error("Clustering key column with position {0} is missing from metadata")]
83+
IncompleteClusteringKey(i32),
8084
}
8185

8286
/// Allows to read current metadata from the cluster
@@ -1606,24 +1610,51 @@ async fn query_tables_schema(
16061610
let mut all_partitioners = query_table_partitioners(conn).await?;
16071611
let mut result = HashMap::new();
16081612

1609-
for ((keyspace_name, table_name), table_result) in tables_schema {
1613+
'tables_loop: for ((keyspace_name, table_name), table_result) in tables_schema {
16101614
let keyspace_and_table_name = (keyspace_name, table_name);
16111615

1612-
let (columns, partition_key_columns, clustering_key_columns) = match table_result {
1616+
let (columns, mut partition_key_columns, mut clustering_key_columns) = match table_result {
16131617
Ok(table) => table,
16141618
Err(e) => {
16151619
let _ = result.insert(keyspace_and_table_name, Err(e));
16161620
continue;
16171621
}
16181622
};
1619-
let mut partition_key = vec!["".to_string(); partition_key_columns.len()];
1620-
for (position, column_name) in partition_key_columns {
1621-
partition_key[position as usize] = column_name;
1623+
1624+
let mut partition_key = Vec::with_capacity(partition_key_columns.len());
1625+
// unwrap: I don't see the point of handling the scenario of fetching over
1626+
// 2 * 10^9 columns.
1627+
for position in 0..partition_key_columns.len().try_into().unwrap() {
1628+
match partition_key_columns.remove(&position) {
1629+
Some(column_name) => partition_key.push(column_name),
1630+
None => {
1631+
result.insert(
1632+
keyspace_and_table_name,
1633+
Err(SingleKeyspaceMetadataError::IncompletePartitionKey(
1634+
position,
1635+
)),
1636+
);
1637+
continue 'tables_loop;
1638+
}
1639+
}
16221640
}
16231641

1624-
let mut clustering_key = vec!["".to_string(); clustering_key_columns.len()];
1625-
for (position, column_name) in clustering_key_columns {
1626-
clustering_key[position as usize] = column_name;
1642+
let mut clustering_key = Vec::with_capacity(clustering_key_columns.len());
1643+
// unwrap: I don't see the point of handling the scenario of fetching over
1644+
// 2 * 10^9 columns.
1645+
for position in 0..clustering_key_columns.len().try_into().unwrap() {
1646+
match clustering_key_columns.remove(&position) {
1647+
Some(column_name) => clustering_key.push(column_name),
1648+
None => {
1649+
result.insert(
1650+
keyspace_and_table_name,
1651+
Err(SingleKeyspaceMetadataError::IncompleteClusteringKey(
1652+
position,
1653+
)),
1654+
);
1655+
continue 'tables_loop;
1656+
}
1657+
}
16271658
}
16281659

16291660
let partitioner = all_partitioners

0 commit comments

Comments
 (0)