Skip to content

Commit 5220a12

Browse files
committed
feat: support domain metadata writes
1 parent ec338ed commit 5220a12

File tree

2 files changed

+50
-7
lines changed

2 files changed

+50
-7
lines changed

kernel/src/actions/mod.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -877,16 +877,16 @@ pub(crate) struct CheckpointMetadata {
877877
#[derive(Debug, Clone, PartialEq, Eq, ToSchema, IntoEngineData)]
878878
#[internal_api]
879879
pub(crate) struct DomainMetadata {
880-
domain: String,
881-
configuration: String,
882-
removed: bool,
880+
pub(crate) domain: String,
881+
pub(crate) configuration: String,
882+
pub(crate) removed: bool,
883883
}
884884

885885
impl DomainMetadata {
886886
// returns true if the domain metadata is an system-controlled domain (all domains that start
887887
// with "delta.")
888888
#[allow(unused)]
889-
fn is_internal(&self) -> bool {
889+
pub(crate) fn is_internal(&self) -> bool {
890890
self.domain.starts_with(INTERNAL_DOMAIN_PREFIX)
891891
}
892892
}

kernel/src/transaction/mod.rs

Lines changed: 46 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
1-
use std::collections::HashSet;
1+
use std::collections::{HashSet, HashMap};
22
use std::iter;
33
use std::sync::{Arc, LazyLock};
44
use std::time::{SystemTime, UNIX_EPOCH};
55

6-
use crate::actions::{get_log_add_schema, get_log_commit_info_schema, get_log_txn_schema};
6+
use crate::actions::domain_metadata::DomainMetadataMap;
7+
use crate::actions::{DomainMetadata, get_log_add_schema, get_log_commit_info_schema, get_log_domain_metadata_schema, get_log_txn_schema};
78
use crate::actions::{CommitInfo, SetTransaction};
89
use crate::error::Error;
910
use crate::expressions::UnaryExpressionOp;
@@ -97,6 +98,7 @@ pub struct Transaction {
9798
// commit-wide timestamp (in milliseconds since epoch) - used in ICT, `txn` action, etc. to
9899
// keep all timestamps within the same commit consistent.
99100
commit_timestamp: i64,
101+
domain_metadata: DomainMetadataMap,
100102
}
101103

102104
impl std::fmt::Debug for Transaction {
@@ -138,6 +140,7 @@ impl Transaction {
138140
add_files_metadata: vec![],
139141
set_transactions: vec![],
140142
commit_timestamp,
143+
domain_metadata: HashMap::new(),
141144
})
142145
}
143146

@@ -165,6 +168,12 @@ impl Transaction {
165168
.into_iter()
166169
.map(|txn| txn.into_engine_data(get_log_txn_schema().clone(), engine));
167170

171+
let set_domain_metadata_actions = self
172+
.domain_metadata
173+
.clone()
174+
.into_values()
175+
.map(|dm| dm.into_engine_data(get_log_domain_metadata_schema().clone(), engine));
176+
168177
// step one: construct the iterator of commit info + file actions we want to commit
169178
let commit_info = CommitInfo::new(
170179
self.commit_timestamp,
@@ -179,7 +188,8 @@ impl Transaction {
179188

180189
let actions = iter::once(commit_info_action)
181190
.chain(add_actions)
182-
.chain(set_transaction_actions);
191+
.chain(set_transaction_actions)
192+
.chain(set_domain_metadata_actions);
183193

184194
// step two: set new commit version (current_version + 1) and path to write
185195
let commit_version = self.read_snapshot.version() + 1;
@@ -271,6 +281,39 @@ impl Transaction {
271281
pub fn add_files(&mut self, add_metadata: Box<dyn EngineData>) {
272282
self.add_files_metadata.push(add_metadata);
273283
}
284+
285+
pub fn add_domain_metadata(&mut self, domain: String, configuration: String) -> DeltaResult<()> {
286+
let domain_metadata = DomainMetadata {
287+
domain: domain.clone(),
288+
configuration: configuration.to_string(),
289+
removed: false,
290+
};
291+
self.validate_domain_metadata(&domain_metadata)?;
292+
self.domain_metadata.insert(domain, domain_metadata);
293+
Ok(())
294+
}
295+
296+
fn validate_domain_metadata(&self, domain_metadata: &DomainMetadata) -> DeltaResult<()> {
297+
if domain_metadata.is_internal() {
298+
return Err(Error::Generic("User metadata cannot be added to system-controlled 'delta.*' domain".to_string()));
299+
}
300+
301+
if self.domain_metadata.contains_key(&domain_metadata.domain) {
302+
return Err(Error::Generic(format!("Metadata for domain {} already specified in this transaction", domain_metadata.domain)));
303+
}
304+
Ok(())
305+
}
306+
307+
pub fn remove_domain_metadata(&mut self, domain: String) -> DeltaResult<()> {
308+
let domain_metadata = DomainMetadata {
309+
domain: domain.clone(),
310+
configuration: "".to_string(),
311+
removed: true,
312+
};
313+
self.validate_domain_metadata(&domain_metadata)?;
314+
self.domain_metadata.insert(domain, domain_metadata);
315+
Ok(())
316+
}
274317
}
275318

276319
/// Convert file metadata provided by the engine into protocol-compliant add actions.

0 commit comments

Comments
 (0)