risingwave_storage/row_serde/
mod.rs

1// Copyright 2022 RisingWave Labs
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//     http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15use std::collections::HashMap;
16
17use risingwave_common::catalog::{ColumnDesc, ColumnId};
18use risingwave_common::row::{OwnedRow, Project, RowExt};
19
20pub mod row_serde_util;
21
22pub mod value_serde;
23
24/// Find out the [`ColumnDesc`] selected with a list of [`ColumnId`].
25///
26/// # Returns
27///
28/// A pair of columns and their indexes in input columns
29pub fn find_columns_by_ids(
30    table_columns: &[ColumnDesc],
31    column_ids: &[ColumnId],
32) -> (Vec<ColumnDesc>, Vec<usize>) {
33    if column_ids.is_empty() {
34        // shortcut
35        return (vec![], vec![]);
36    }
37    let id_to_columns = table_columns
38        .iter()
39        .enumerate()
40        .map(|(index, c)| (c.column_id, (c.clone(), index)))
41        .collect::<HashMap<_, _>>();
42    column_ids
43        .iter()
44        .map(|id| id_to_columns.get(id).expect("column id not found").clone())
45        .unzip()
46}
47
48#[derive(Clone)]
49pub struct ColumnMapping {
50    output_indices: Vec<usize>,
51}
52
53impl ColumnMapping {
54    /// Create a mapping with given `table_columns` projected on the `column_ids`.
55    pub fn new(output_indices: Vec<usize>) -> Self {
56        Self { output_indices }
57    }
58
59    /// Project a row with this mapping
60    pub fn project(&self, origin_row: OwnedRow) -> Project<'_, OwnedRow> {
61        origin_row.project(&self.output_indices)
62    }
63}
64
65#[cfg(test)]
66mod test {
67    use std::fmt::Debug;
68
69    use expect_test::{Expect, expect};
70    use risingwave_common::types::DataType;
71
72    use super::*;
73
74    fn check(actual: impl Debug, expect: Expect) {
75        let actual = format!("{:#?}", actual);
76        expect.assert_eq(&actual);
77    }
78
79    #[test]
80    fn test_find_columns_by_ids() {
81        let table_columns = vec![
82            ColumnDesc::unnamed(1.into(), DataType::Varchar),
83            ColumnDesc::unnamed(2.into(), DataType::Int64),
84            ColumnDesc::unnamed(3.into(), DataType::Int16),
85        ];
86        let column_ids = vec![2.into(), 3.into()];
87        let result = find_columns_by_ids(&table_columns, &column_ids);
88        check(
89            result,
90            expect![[r#"
91                (
92                    [
93                        ColumnDesc {
94                            data_type: Int64,
95                            column_id: #2,
96                            name: "",
97                            generated_or_default_column: None,
98                            description: None,
99                            additional_column: AdditionalColumn {
100                                column_type: None,
101                            },
102                            version: Pr13707,
103                            system_column: None,
104                            nullable: true,
105                        },
106                        ColumnDesc {
107                            data_type: Int16,
108                            column_id: #3,
109                            name: "",
110                            generated_or_default_column: None,
111                            description: None,
112                            additional_column: AdditionalColumn {
113                                column_type: None,
114                            },
115                            version: Pr13707,
116                            system_column: None,
117                            nullable: true,
118                        },
119                    ],
120                    [
121                        1,
122                        2,
123                    ],
124                )"#]],
125        );
126
127        let table_columns = vec![
128            ColumnDesc::unnamed(2.into(), DataType::Int64),
129            ColumnDesc::unnamed(1.into(), DataType::Varchar),
130            ColumnDesc::unnamed(3.into(), DataType::Int16),
131        ];
132        let column_ids = vec![2.into(), 1.into()];
133        let result = find_columns_by_ids(&table_columns, &column_ids);
134        check(
135            result,
136            expect![[r#"
137                (
138                    [
139                        ColumnDesc {
140                            data_type: Int64,
141                            column_id: #2,
142                            name: "",
143                            generated_or_default_column: None,
144                            description: None,
145                            additional_column: AdditionalColumn {
146                                column_type: None,
147                            },
148                            version: Pr13707,
149                            system_column: None,
150                            nullable: true,
151                        },
152                        ColumnDesc {
153                            data_type: Varchar,
154                            column_id: #1,
155                            name: "",
156                            generated_or_default_column: None,
157                            description: None,
158                            additional_column: AdditionalColumn {
159                                column_type: None,
160                            },
161                            version: Pr13707,
162                            system_column: None,
163                            nullable: true,
164                        },
165                    ],
166                    [
167                        0,
168                        1,
169                    ],
170                )"#]],
171        );
172    }
173}