iceberg-cpp
Loading...
Searching...
No Matches
update_partition_spec.h
Go to the documentation of this file.
1/*
2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements. See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership. The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the
7 * "License"); you may not use this file except in compliance
8 * with the License. You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing,
13 * software distributed under the License is distributed on an
14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 * KIND, either express or implied. See the License for the
16 * specific language governing permissions and limitations
17 * under the License.
18 */
19
20#pragma once
21
24
25#include <functional>
26#include <memory>
27#include <string>
28#include <unordered_map>
29#include <unordered_set>
30#include <vector>
31
32#include "iceberg/iceberg_export.h"
33#include "iceberg/result.h"
34#include "iceberg/type_fwd.h"
36#include "iceberg/util/string_util.h"
37
38namespace iceberg {
39
44class ICEBERG_EXPORT UpdatePartitionSpec : public PendingUpdate {
45 public:
46 static Result<std::shared_ptr<UpdatePartitionSpec>> Make(
47 std::shared_ptr<TransactionContext> ctx);
48
49 ~UpdatePartitionSpec() override;
50
52 UpdatePartitionSpec& CaseSensitive(bool is_case_sensitive);
53
61 UpdatePartitionSpec& AddField(std::string_view source_name);
62
68 UpdatePartitionSpec& AddField(const std::shared_ptr<Term>& term,
69 std::string_view part_name = "");
70
75 UpdatePartitionSpec& RemoveField(std::string_view name);
76
85 UpdatePartitionSpec& RemoveField(const std::shared_ptr<Term>& term);
86
92 UpdatePartitionSpec& RenameField(std::string_view name, std::string new_name);
93
99 UpdatePartitionSpec& AddNonDefaultSpec();
100
101 Kind kind() const final { return Kind::kUpdatePartitionSpec; }
102
108 bool IsRetryable() const override { return false; }
109
110 struct ApplyResult {
111 std::shared_ptr<PartitionSpec> spec;
112 bool set_as_default;
113 };
114 Result<ApplyResult> Apply();
115
116 private:
117 explicit UpdatePartitionSpec(std::shared_ptr<TransactionContext> ctx);
118
120 using TransformKey = std::pair<int32_t, std::string>;
121
123 struct TransformKeyHash {
124 size_t operator()(const TransformKey& key) const {
125 return 31 * std::hash<int32_t>{}(key.first) + std::hash<std::string>{}(key.second);
126 }
127 };
128
130 int32_t AssignFieldId();
131
142 PartitionField RecycleOrCreatePartitionField(int32_t source_id,
143 std::shared_ptr<Transform> transform,
144 std::string_view name);
145
147 UpdatePartitionSpec& AddFieldInternal(std::string_view name, int32_t source_id,
148 const std::shared_ptr<Transform>& transform);
149
151 Result<std::string> GeneratePartitionName(
152 int32_t source_id, const std::shared_ptr<Transform>& transform) const;
153
155 static bool IsTimeTransform(const std::shared_ptr<Transform>& transform);
156
158 static bool IsVoidTransform(const PartitionField& field);
159
161 void CheckForRedundantAddedPartitions(const PartitionField& field);
162
164 UpdatePartitionSpec& RewriteDeleteAndAddField(const PartitionField& existing,
165 std::string_view name);
166
168 UpdatePartitionSpec& RemoveFieldByTransform(const TransformKey& key,
169 std::string_view term_str);
170
172 static std::unordered_map<std::string, const PartitionField*, StringHash, StringEqual>
173 IndexSpecByName(const PartitionSpec& spec);
174
176 static std::unordered_map<TransformKey, const PartitionField*, TransformKeyHash>
177 IndexSpecByTransform(const PartitionSpec& spec);
178
180 void BuildHistoricalFieldsIndex();
181
182 // Configuration
183 int32_t format_version_;
184 std::shared_ptr<PartitionSpec> spec_;
185 std::shared_ptr<Schema> schema_;
186 bool case_sensitive_{true};
187 bool set_as_default_{true};
188 int32_t last_assigned_partition_id_;
189
190 // Indexes for existing fields
191 std::unordered_map<std::string, const PartitionField*, StringHash, StringEqual>
192 name_to_field_;
193 std::unordered_map<TransformKey, const PartitionField*, TransformKeyHash>
194 transform_to_field_;
195
196 // Index for historical partition fields (V2+ only) for efficient recycling.
197 // Maps (source_id, transform_string) -> PartitionField from all historical specs.
198 std::unordered_map<TransformKey, PartitionField, TransformKeyHash> historical_fields_;
199
200 // Pending changes
201 std::vector<PartitionField> adds_;
202 std::unordered_set<std::string, StringHash, StringEqual> added_field_names_;
203 std::unordered_map<int32_t, std::string> added_time_fields_;
204 std::unordered_map<TransformKey, std::string, TransformKeyHash>
205 transform_to_added_field_;
206 std::unordered_set<int32_t> deletes_;
207 std::unordered_map<std::string, std::string, StringHash, StringEqual> renames_;
208};
209
210} // namespace iceberg
Base class for all kinds of table metadata updates.
Definition pending_update.h:41
API for partition spec evolution.
Definition update_partition_spec.h:44
bool IsRetryable() const override
Partition spec updates are not retryable.
Definition update_partition_spec.h:108
Kind kind() const final
Return the kind of this pending update.
Definition update_partition_spec.h:101
Definition update_partition_spec.h:110