in src/iceberg/json_internal.cc [1015:1066]
Status ParsePartitionSpecs(const nlohmann::json& json, int8_t format_version,
const std::shared_ptr<Schema>& current_schema,
int32_t& default_spec_id,
std::vector<std::shared_ptr<PartitionSpec>>& partition_specs) {
if (json.contains(kPartitionSpecs)) {
ICEBERG_ASSIGN_OR_RAISE(auto spec_array,
GetJsonValue<nlohmann::json>(json, kPartitionSpecs));
if (!spec_array.is_array()) {
return JsonParseError("Cannot parse partition specs from non-array: {}",
spec_array.dump());
}
ICEBERG_ASSIGN_OR_RAISE(default_spec_id, GetJsonValue<int32_t>(json, kDefaultSpecId));
for (const auto& spec_json : spec_array) {
ICEBERG_ASSIGN_OR_RAISE(auto spec,
PartitionSpecFromJson(current_schema, spec_json));
partition_specs.push_back(std::move(spec));
}
} else {
if (format_version != 1) {
return JsonParseError("{} must exist in format v{}", kPartitionSpecs,
format_version);
}
ICEBERG_ASSIGN_OR_RAISE(auto partition_spec_json,
GetJsonValue<nlohmann::json>(json, kPartitionSpec));
if (!partition_spec_json.is_array()) {
return JsonParseError("Cannot parse v1 partition spec from non-array: {}",
partition_spec_json.dump());
}
int32_t next_partition_field_id = PartitionSpec::kLegacyPartitionDataIdStart;
std::vector<PartitionField> fields;
for (const auto& entry_json : partition_spec_json) {
ICEBERG_ASSIGN_OR_RAISE(auto field, PartitionFieldFromJson(entry_json));
int32_t field_id = field->field_id();
if (field_id == SchemaField::kInvalidFieldId) {
// If the field ID is not set, we need to assign a new one
field_id = next_partition_field_id++;
}
fields.emplace_back(field->source_id(), field_id, std::string(field->name()),
std::move(field->transform()));
}
auto spec = std::make_unique<PartitionSpec>(
current_schema, PartitionSpec::kInitialSpecId, std::move(fields));
default_spec_id = spec->spec_id();
partition_specs.push_back(std::move(spec));
}
return {};
}