common_grpc_expr/
delete.rs1use std::collections::HashMap;
16
17use api::helper::ColumnDataTypeWrapper;
18use api::v1::{Column, DeleteRequest as GrpcDeleteRequest};
19use datatypes::prelude::ConcreteDataType;
20use snafu::{ensure, ResultExt};
21use table::requests::DeleteRequest;
22
23use crate::error::{ColumnDataTypeSnafu, IllegalDeleteRequestSnafu, Result};
24use crate::insert::add_values_to_builder;
25
26pub fn to_table_delete_request(
27 catalog_name: &str,
28 schema_name: &str,
29 request: GrpcDeleteRequest,
30) -> Result<DeleteRequest> {
31 let row_count = request.row_count as usize;
32
33 let mut key_column_values = HashMap::with_capacity(request.key_columns.len());
34 for Column {
35 column_name,
36 values,
37 null_mask,
38 datatype,
39 datatype_extension,
40 ..
41 } in request.key_columns
42 {
43 let Some(values) = values else { continue };
44
45 let datatype: ConcreteDataType =
46 ColumnDataTypeWrapper::try_new(datatype, datatype_extension)
47 .context(ColumnDataTypeSnafu)?
48 .into();
49 let vector = add_values_to_builder(datatype, values, row_count, null_mask)?;
50
51 ensure!(
52 key_column_values
53 .insert(column_name.clone(), vector)
54 .is_none(),
55 IllegalDeleteRequestSnafu {
56 reason: format!("Duplicated column '{column_name}' in delete request.")
57 }
58 );
59 }
60
61 Ok(DeleteRequest {
62 catalog_name: catalog_name.to_string(),
63 schema_name: schema_name.to_string(),
64 table_name: request.table_name,
65 key_column_values,
66 })
67}
68
69#[cfg(test)]
70mod tests {
71 use std::sync::Arc;
72
73 use api::v1::column::Values;
74 use api::v1::ColumnDataType;
75 use datatypes::prelude::{ScalarVector, VectorRef};
76 use datatypes::vectors::{Int32Vector, StringVector};
77
78 use super::*;
79
80 #[test]
81 fn test_to_table_delete_request() {
82 let grpc_request = GrpcDeleteRequest {
83 table_name: "foo".to_string(),
84 key_columns: vec![
85 Column {
86 column_name: "id".to_string(),
87 values: Some(Values {
88 i32_values: vec![1, 2, 3],
89 ..Default::default()
90 }),
91 datatype: ColumnDataType::Int32 as i32,
92 ..Default::default()
93 },
94 Column {
95 column_name: "name".to_string(),
96 values: Some(Values {
97 string_values: vec!["a".to_string(), "b".to_string(), "c".to_string()],
98 ..Default::default()
99 }),
100 datatype: ColumnDataType::String as i32,
101 ..Default::default()
102 },
103 ],
104 row_count: 3,
105 };
106
107 let mut request =
108 to_table_delete_request("foo_catalog", "foo_schema", grpc_request).unwrap();
109
110 assert_eq!(request.catalog_name, "foo_catalog");
111 assert_eq!(request.schema_name, "foo_schema");
112 assert_eq!(request.table_name, "foo");
113 assert_eq!(
114 Arc::new(Int32Vector::from_slice(vec![1, 2, 3])) as VectorRef,
115 request.key_column_values.remove("id").unwrap()
116 );
117 assert_eq!(
118 Arc::new(StringVector::from_slice(&["a", "b", "c"])) as VectorRef,
119 request.key_column_values.remove("name").unwrap()
120 );
121 assert!(request.key_column_values.is_empty());
122 }
123}