Hacktoberfest 2026:維護者為十月標記出來的 issue,仍然開放、適合新手。 瀏覽 Hacktoberfest issue

Bug: dynamic_partition_overwrite silently skips spec-0 manifests after partition spec evolution

已關閉
#3,148 1 則留言 0 個 reaction 已指派 0 人 在 GitHub 檢視

維護者通常 1 天內回覆

還沒有人認領這個 Issue。

評估

難度
4/5
預估耗時
3-5 天
新手友好度
70/100
Issue 類型
缺陷
描述清晰度
描述清楚
活躍度
活躍
技術堆疊
python
領域
databases

研究方向

從 table/init.py 中的 Table.dynamic_partition_overwrite 開始,接著追蹤 _build_partition_projection 以及 #3011 中的 manifest-pruning 變更。重現 issue 中所描述的混合 spec-0/spec-1 snapshot,並與 #1108 中先前的相關 fix 比較。完成的標準是回歸測試確認覆寫會從兩個歷史 spec 中移除相符的資料列,同時不會刪除無關資料。

由索引模型根據 Issue 內容生成。

描述

stale

Summary

dynamic_partition_overwrite produces incorrect results when a table has undergone
partition spec evolution. Manifests written under older specs are silently skipped
by the manifest pruning logic introduced in #3011, leaving stale data files that
should have been deleted.

Root cause

In Table.dynamic_partition_overwrite (table/__init__.py), the delete predicate
is built using only the current partition spec:

delete_filter = self._build_partition_predicate(
    partition_records=partitions_to_overwrite,
    spec=self.table_metadata.spec(),       # always current spec
    schema=self.table_metadata.schema()
)

A snapshot with mixed partition_spec_ids (spec-0 and spec-1 manifests) passes
this single predicate to _DeleteFiles. The manifest evaluator in _build_partition_projection
uses inclusive_projection(schema, spec) — when projecting a spec-1 predicate
(e.g. category=A AND region=us) through spec-0 (which only has category), the
region reference has no corresponding partition field, causing the evaluator to
incorrectly skip spec-0 manifests entirely.

Reproduction

import tempfile, pyarrow as pa
from pyiceberg.catalog import load_catalog
from pyiceberg.schema import Schema
from pyiceberg.types import NestedField, StringType, LongType
from pyiceberg.partitioning import PartitionSpec, PartitionField
from pyiceberg.transforms import IdentityTransform

schema = Schema(
    NestedField(1, "category", StringType(), required=False),
    NestedField(2, "region",   StringType(), required=False),
    NestedField(3, "value",    LongType(),   required=False),
)
spec_v0 = PartitionSpec(
    PartitionField(source_id=1, field_id=1000, transform=IdentityTransform(), name="category")
)

with tempfile.TemporaryDirectory() as warehouse:
    catalog = load_catalog("test", **{"type": "sql", "uri": f"sqlite:///{warehouse}/catalog.db", "warehouse": f"file://{warehouse}"})
    catalog.create_namespace("default")
    table = catalog.create_table("default.test", schema=schema, partition_spec=spec_v0)

    # Write under spec 0
    table.append(pa.table({"category": ["A","A","B"], "region": [None,None,None], "value": [1,2,10]}))

    # Evolve spec
    with table.update_spec() as u:
        u.add_field("region", IdentityTransform(), "region")
    table = catalog.load_table("default.test")

    # Write under spec 1
    table.append(pa.table({"category": ["A","B"], "region": ["us","us"], "value": [100,200]}))

    # Overwrite category=A — should delete ALL A rows (both specs)
    table.dynamic_partition_overwrite(
        pa.table({"category": ["A"], "region": ["us"], "value": [999]})
    )

    result = table.scan().to_arrow().to_pydict()
    a_values = [v for c,v in zip(result["category"], result["value"]) if c == "A"]
    print(a_values)  # BUG: prints [1, 2, 100, 999] — stale rows from spec-0 not deleted
                     # EXPECTED: [999]

Fix

Build the delete predicate per historical spec present in the snapshot, projecting
the new data files' partition values into each spec's coordinate space before evaluating.
PR with fix and regression tests to follow.

Related

  • #3011 (introduced the manifest pruning optimization)
  • #1108 (prior related fix by @Fokko for spec evolution in manifest rewriting)
主要語言
Python
星號
1.2k
分支
618
平均合併
1 天 19 小時
30 天內合併 PR
51

環境準備

  • 沒有 Dockerfile 或 Docker Compose 檔案
  • 有 Pull Request 範本
  • 沒有貢獻指南

從這裡開始

  1. 先讀完整個 Issue,再讀專案的貢獻指南。
  2. 在 Issue 下留言說明你要接手 —— 這能避免兩個人做同樣的事。
  3. Fork 儲存庫,在一個分支上完成修改。
  4. 送出 Pull Request,並在描述裡引用這個 Issue 編號。

apache/iceberg-python 的其他 Issue

查看 apache/iceberg-python 的全部 Issue

相似的 Issue

更多 Python Issue

把新 issue 寄到你的電子郵件信箱

精選適合新手參與的 GitHub issue 摘要。