Your browser sucks, JavaScript disabled! Gunnar's console needs JavaScript and WebAssembly. Git over SSH on port 2222 does not.

nordisk/skade

vendor/iceberg-arrow59/src/transaction/update_partition_spec.rs

// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.

//! Partition spec evolution as a transaction action (skade patch, 2026-10-17):
//! `TableUpdate::AddSpec` + `TableUpdate::SetDefaultSpec` existed only at the
//! catalog level; this is the action a caller reaches through
//! [`Transaction::add_partition_spec`](crate::transaction::Transaction::add_partition_spec).
//! The table's existing data files keep their spec (unpartitioned files of
//! spec 0 are read as before); files written after the commit carry the new
//! spec, and a rewrite of the old files moves them over.

use std::sync::Arc;

use async_trait::async_trait;

use crate::spec::{TableMetadataBuilder, UnboundPartitionSpec};
use crate::table::Table;
use crate::transaction::action::{ActionCommit, TransactionAction};
use crate::{Result, TableRequirement, TableUpdate};

/// Add a partition spec to a table, and make it the default unless
/// [`keep_default`](Self::keep_default) says otherwise.
pub struct AddPartitionSpecAction {
    spec: UnboundPartitionSpec,
    set_default: bool,
}

impl AddPartitionSpecAction {
    pub(crate) fn new(spec: UnboundPartitionSpec) -> Self {
        Self { spec, set_default: true }
    }

    /// Add the spec without making it the default (default: make it the default).
    pub fn keep_default(mut self) -> Self {
        self.set_default = false;
        self
    }
}

#[async_trait]
impl TransactionAction for AddPartitionSpecAction {
    async fn commit(self: Arc<Self>, table: &Table) -> Result<ActionCommit> {
        let metadata = table.metadata();
        let mut updates = vec![TableUpdate::AddSpec { spec: self.spec.clone() }];
        if self.set_default {
            updates.push(TableUpdate::SetDefaultSpec { spec_id: TableMetadataBuilder::LAST_ADDED });
        }
        Ok(ActionCommit::new(updates, vec![
            TableRequirement::UuidMatch { uuid: metadata.uuid() },
            TableRequirement::DefaultSpecIdMatch { default_spec_id: metadata.default_partition_spec_id() },
        ]))
    }
}