Skip to content

Commit f7bcb57

Browse files
[python][ray] Rebase exact-range self-merge updates
1 parent 3e510cf commit f7bcb57

2 files changed

Lines changed: 34 additions & 19 deletions

File tree

‎paimon-python/pypaimon/ray/row_id_conflict_rewriter.py‎

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -86,11 +86,11 @@ def commit_self_merge_with_compaction_retry(
8686
if result is not None:
8787
current_updates = result.update_messages
8888
logger.info(
89-
"Rewrote %d stale self-merge file(s) against snapshot %d "
90-
"before committing to table %s.",
91-
result.rewritten_file_count,
89+
"Rebased stale self-merge updates against snapshot %d "
90+
"before committing to table %s; rewrote %d file(s).",
9291
latest_snapshot.id,
9392
table.identifier,
93+
result.rewritten_file_count,
9494
)
9595

9696
# Match Spark's PaimonSparkWriter: every outer rebase attempt creates a
@@ -152,11 +152,11 @@ def commit_self_merge_with_compaction_retry(
152152
raise conflict
153153

154154
logger.info(
155-
"Rewrote %d stale self-merge file(s) against snapshot %d "
156-
"before retrying commit to table %s.",
157-
result.rewritten_file_count,
155+
"Rebased stale self-merge updates against snapshot %d "
156+
"before retrying commit to table %s; rewrote %d file(s).",
158157
latest_snapshot.id,
159158
table.identifier,
159+
result.rewritten_file_count,
160160
)
161161
_retry_wait(table, retry_count)
162162
retry_count += 1
@@ -241,8 +241,9 @@ def _rewrite_updates(
241241
latest_snapshot.next_row_id,
242242
)
243243
]
244-
if not candidates:
245-
return None
244+
# Compaction can replace an anchor while preserving its exact row-id
245+
# range. There is nothing to rewrite then, but the snapshot check below
246+
# still needs to advance past that compaction.
246247
if not _ranges_are_still_covered(current_files, candidates):
247248
return None
248249

‎paimon-python/pypaimon/tests/ray_data_evolution_merge_into_test.py‎

Lines changed: 25 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -115,16 +115,18 @@ def _snapshot_id(self, target):
115115
return snap.id if snap is not None else None
116116

117117
def _compact_all_data_files(self, table):
118-
"""Replace all current data files with one COMPACT output file."""
118+
"""Replace current data files with one COMPACT file per file group."""
119119
from pypaimon.table.special_fields import SpecialFields
120120

121121
read_builder = table.new_read_builder().with_projection(
122122
list(table.field_names) + [SpecialFields.ROW_ID.name]
123123
)
124124
plan = read_builder.new_scan().plan_for_write()
125-
old_files = [
126-
file for split in plan.splits() for file in split.files
127-
]
125+
old_files_by_group = {}
126+
for split in plan.splits():
127+
old_files_by_group.setdefault(
128+
(tuple(split.partition.values), split.bucket), [],
129+
).extend(split.files)
128130
current = read_builder.new_read().to_arrow(plan.splits()).sort_by(
129131
[(SpecialFields.ROW_ID.name, 'ascending')]
130132
).select(list(table.field_names))
@@ -133,12 +135,20 @@ def _compact_all_data_files(self, table):
133135
writer = write_builder.new_write()
134136
writer.write_arrow(current)
135137
messages = writer.prepare_commit()
136-
self.assertEqual(len(messages), 1)
137-
self.assertEqual(len(messages[0].new_files), 1)
138-
messages[0].new_files = [
139-
messages[0].new_files[0].assign_first_row_id(0)
140-
]
141-
messages[0].deleted_files.extend(old_files)
138+
self.assertEqual(
139+
{(message.partition, message.bucket) for message in messages},
140+
set(old_files_by_group),
141+
)
142+
for message in messages:
143+
old_files = old_files_by_group[
144+
(message.partition, message.bucket)
145+
]
146+
self.assertEqual(len(message.new_files), 1)
147+
first_row_id = min(file.first_row_id for file in old_files)
148+
message.new_files = [
149+
message.new_files[0].assign_first_row_id(first_row_id)
150+
]
151+
message.deleted_files.extend(old_files)
142152

143153
commit = write_builder.new_commit()
144154
file_store_commit = commit.file_store_commit
@@ -2376,7 +2386,11 @@ def test_self_merge_rebases_staged_updates_after_compaction(self):
23762386
target = 'default.tbl_{}'.format(uuid.uuid4().hex[:8])
23772387
self.catalog.create_table(
23782388
target,
2379-
Schema.from_pyarrow_schema(schema, options=options),
2389+
Schema.from_pyarrow_schema(
2390+
schema,
2391+
partition_keys=['content_key'],
2392+
options=options,
2393+
),
23802394
False,
23812395
)
23822396

0 commit comments

Comments
 (0)