Skip to content

Commit 40b5efe

Browse files
Youngwbclaude
andcommitted
[BugFix] Key MV pinned-range map by Table#getUUID() so it is cross-database-unique
The pinned-range map is keyed by a table identifier that producers (setupPinnedRangesIfNeeded) and consumers (MVPCTRefreshPlanBuilder, PartitionDiffer#pinnedRangeFor) both compute. Using Table#getTableIdentifier() keys native tables by their bare name, which is not unique across databases: an MV referencing two same-named tables in different databases overwrites one entry, so one table's pinned snapshot is lost. Key the map by Table#getUUID() on both sides instead — it is cross-database-unique for every table kind (the table id for native/cloud-native, catalog.db.table.uuid for external) and is identical at producer and every consumer. IcebergTable#getUUID() also gains an instanceof-BaseTable guard so a non-BaseTable native table degrades to an empty uuid instead of a ClassCastException, matching getTableIdentifier(). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Signed-off-by: Youngwb <yangwenbo_mailbox@163.com>
1 parent c613e0f commit 40b5efe

4 files changed

Lines changed: 11 additions & 9 deletions

File tree

fe/fe-core/src/main/java/com/starrocks/catalog/IcebergTable.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -173,7 +173,9 @@ public String getCatalogTableName() {
173173
@Override
174174
public String getUUID() {
175175
if (CatalogMgr.isExternalCatalog(catalogName)) {
176-
String uuid = ((BaseTable) getNativeTable()).operations().current().uuid();
176+
org.apache.iceberg.Table nativeTable = getNativeTable();
177+
String uuid = nativeTable instanceof BaseTable
178+
? ((BaseTable) nativeTable).operations().current().uuid() : null;
177179
return String.join(".", catalogName, catalogDBName, catalogTableName,
178180
uuid == null ? "" : uuid);
179181
} else {

fe/fe-core/src/main/java/com/starrocks/scheduler/mv/MVRefreshProcessor.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -340,10 +340,10 @@ protected void setupPinnedRangesIfNeeded() {
340340
continue;
341341
}
342342
final TvrVersionRange pinned = TvrTableSnapshot.of(tvr.end());
343-
// Must key by Table#getTableIdentifier() to match every consumer (MVPCTRefreshPlanBuilder,
344-
// PartitionDiffer#pinnedRangeFor). For native OLAP BaseTableInfo#getTableIdentifier() yields
345-
// the table id but Table yields the name, so the old key silently missed every lookup.
346-
pinnedMap.put(info.getBaseTable().getTableIdentifier(), pinned);
343+
// Key by getUUID() — cross-db-unique and identical at every consumer
344+
// (MVPCTRefreshPlanBuilder, PartitionDiffer#pinnedRangeFor). A bare table
345+
// name would collide across databases.
346+
pinnedMap.put(info.getBaseTable().getUUID(), pinned);
347347

348348
if (info instanceof PCTTableSnapshotInfo) {
349349
((PCTTableSnapshotInfo) info).setPinnedRange(pinned);

fe/fe-core/src/main/java/com/starrocks/scheduler/mv/pct/MVPCTRefreshPlanBuilder.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -142,12 +142,12 @@ private InsertStmt buildInsertPlan(InsertStmt insertStmt,
142142
for (Map.Entry<String, TableRelation> entry : tableRelations.entries()) {
143143
TableRelation relation = entry.getValue();
144144
Table table = relation.getTable();
145-
// Skip null here to avoid NPE on getTableIdentifier(); the relation-grouping loop below
145+
// Skip null here to avoid NPE on getUUID(); the relation-grouping loop below
146146
// throws a controlled AnalysisException for any base table that resolved to null.
147147
if (table == null) {
148148
continue;
149149
}
150-
TvrVersionRange pinned = pinnedMap.get(table.getTableIdentifier());
150+
TvrVersionRange pinned = pinnedMap.get(table.getUUID());
151151
if (pinned != null) {
152152
relation.setTvrVersionRange(pinned);
153153
logger.info("Inject pinned TVR {} into table relation {} for scan",

fe/fe-core/src/main/java/com/starrocks/sql/common/PartitionDiffer.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ public abstract class PartitionDiffer {
3535
// consider partition_ttl_number and mv refresh will consider it to avoid creating too much partitions
3636
protected final MVTimelinessArbiter.QueryRewriteParams queryRewriteParams;
3737

38-
// Pinned ranges keyed by Table.getTableIdentifier(). Empty means no pinning.
38+
// Pinned ranges keyed by Table.getUUID(). Empty means no pinning.
3939
protected Map<String, TvrVersionRange> pinnedRangeByTableIdentifier = Collections.emptyMap();
4040

4141
public PartitionDiffer(MaterializedView mv, MVTimelinessArbiter.QueryRewriteParams queryRewriteParams) {
@@ -49,7 +49,7 @@ public void setPinnedRanges(Map<String, TvrVersionRange> pinnedRangeByTableIdent
4949
}
5050

5151
protected TvrVersionRange pinnedRangeFor(Table table) {
52-
return pinnedRangeByTableIdentifier.get(table.getTableIdentifier());
52+
return pinnedRangeByTableIdentifier.get(table.getUUID());
5353
}
5454

5555
/**

0 commit comments

Comments
 (0)