Bug: dynamic_partition_overwrite silently skips spec-0 manifests after partition spec evolution
維護者通常 1 天內回覆
還沒有人認領這個 Issue。
評估
研究方向
從 table/init.py 中的 Table.dynamic_partition_overwrite 開始,接著追蹤 _build_partition_projection 以及 #3011 中的 manifest-pruning 變更。重現 issue 中所描述的混合 spec-0/spec-1 snapshot,並與 #1108 中先前的相關 fix 比較。完成的標準是回歸測試確認覆寫會從兩個歷史 spec 中移除相符的資料列,同時不會刪除無關資料。
由索引模型根據 Issue 內容生成。
描述
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 範本
- 沒有貢獻指南
從這裡開始
- 先讀完整個 Issue,再讀專案的貢獻指南。
- 在 Issue 下留言說明你要接手 —— 這能避免兩個人做同樣的事。
- Fork 儲存庫,在一個分支上完成修改。
- 送出 Pull Request,並在描述裡引用這個 Issue 編號。
apache/iceberg-python 的其他 Issue
-
難度 2/5 1-3 小時 新手友好度 70/100
apache/iceberg-python#4093 ·
維護者通常 1 天內回覆
-
View does not expose metadata_location: RestCatalog.load_view discards it from the server's response可能已有人在做 @Soumo-git-hub 於 5 天前認領。 未關閉kind:bug
難度 2/5 1-3 小時 新手友好度 84/100
apache/iceberg-python#4073 · 1 則留言 ·
維護者通常 1 天內回覆
-
難度 2/5 1-3 小時 新手友好度 70/100
apache/iceberg-python#4010 · 3 則留言 · 1 個 reaction ·
維護者通常 1 天內回覆
-
to_bytes silently rescales a Decimal with a negative scale可能已有人在做 @Rodrigo-Palma 於 25 天前認領。 未關閉
難度 2/5 1-3 小時 新手友好度 78/100
apache/iceberg-python#3996 ·
維護者通常 1 天內回覆
-
Deletion vector bitmap count is read from the blob and used as a loop bound without validation可能已有人在做 @ghoshp83 於 25 天前認領。 未關閉bug
難度 2/5 1-3 小時 新手友好度 72/100
apache/iceberg-python#3979 ·
維護者通常 1 天內回覆
查看 apache/iceberg-python 的全部 Issue
相似的 Issue
-
SSM GetParameter throttling during concurrent workflow launches可能已有人在做 @alexiswl 今天認領。 未關閉
難度 2/5 1-3 小時 新手友好度 80/100
-
[Bug] Dev image build fails: `npm install` in the root Dockerfile runs out of memory (exit 134)可能已有人在做 @andest01 今天認領。 未關閉
難度 2/5 1-3 小時 新手友好度 75/100
維護者通常 1 天內回覆
-
Rename FunctionalRole BOT_DEV to DEV_STAFF可能已有人在做 關聯的 PR 仍在進行中或已合併。 未關閉enhancement good first issue
難度 2/5 1-3 小時 新手友好度 79/100
pesu-dev/discord_bot#97 ·
-
難度 1/5 1-3 小時 新手友好度 88/100
gradio-app/gradio#13964 ·
維護者通常 1 天內回覆
-
難度 1/5 1 小時以內 新手友好度 93/100
BSData/horus-heresy-3rd-edition#3232 · 1 則留言 ·
維護者通常 1 天內回覆