parquet/file/
column_crypto_metadata.rs

1// Licensed to the Apache Software Foundation (ASF) under one
2// or more contributor license agreements.  See the NOTICE file
3// distributed with this work for additional information
4// regarding copyright ownership.  The ASF licenses this file
5// to you under the Apache License, Version 2.0 (the
6// "License"); you may not use this file except in compliance
7// with the License.  You may obtain a copy of the License at
8//
9//   http://www.apache.org/licenses/LICENSE-2.0
10//
11// Unless required by applicable law or agreed to in writing,
12// software distributed under the License is distributed on an
13// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14// KIND, either express or implied.  See the License for the
15// specific language governing permissions and limitations
16// under the License.
17
18//! Column chunk encryption metadata
19
20use std::io::Write;
21
22use crate::errors::{ParquetError, Result};
23use crate::file::metadata::HeapSize;
24use crate::parquet_thrift::{
25    read_thrift_vec, ElementType, FieldType, ReadThrift, ThriftCompactInputProtocol,
26    ThriftCompactOutputProtocol, WriteThrift, WriteThriftField,
27};
28use crate::{thrift_struct, thrift_union};
29
30// define this and ColumnCryptoMetadata here so they're only defined when
31// the encryption feature is enabled
32
33thrift_struct!(
34/// Encryption metadata for a column chunk encrypted with a column-specific key
35pub struct EncryptionWithColumnKey {
36  /// Path to the column in the Parquet schema
37  1: required list<string> path_in_schema
38
39  /// Path to the column in the Parquet schema
40  2: optional binary key_metadata
41}
42);
43
44impl HeapSize for EncryptionWithColumnKey {
45    fn heap_size(&self) -> usize {
46        self.path_in_schema.heap_size() + self.key_metadata.heap_size()
47    }
48}
49
50thrift_union!(
51/// ColumnCryptoMetadata for a column chunk
52union ColumnCryptoMetaData {
53  1: ENCRYPTION_WITH_FOOTER_KEY
54  2: (EncryptionWithColumnKey) ENCRYPTION_WITH_COLUMN_KEY
55}
56);
57
58impl HeapSize for ColumnCryptoMetaData {
59    fn heap_size(&self) -> usize {
60        match self {
61            Self::ENCRYPTION_WITH_FOOTER_KEY => 0,
62            Self::ENCRYPTION_WITH_COLUMN_KEY(path) => path.heap_size(),
63        }
64    }
65}
66
67#[cfg(test)]
68mod tests {
69    use super::*;
70    use crate::parquet_thrift::tests::test_roundtrip;
71
72    #[test]
73    fn test_column_crypto_roundtrip() {
74        test_roundtrip(ColumnCryptoMetaData::ENCRYPTION_WITH_FOOTER_KEY);
75
76        let path_in_schema = vec!["foo".to_owned(), "bar".to_owned(), "really".to_owned()];
77        let key_metadata = vec![1u8; 32];
78        test_roundtrip(ColumnCryptoMetaData::ENCRYPTION_WITH_COLUMN_KEY(
79            EncryptionWithColumnKey {
80                path_in_schema: path_in_schema.clone(),
81                key_metadata: None,
82            },
83        ));
84        test_roundtrip(ColumnCryptoMetaData::ENCRYPTION_WITH_COLUMN_KEY(
85            EncryptionWithColumnKey {
86                path_in_schema,
87                key_metadata: Some(key_metadata),
88            },
89        ));
90    }
91}