morrySnow commented on code in PR #67891:
URL: https://github.com/apache/doris/pull/67891#discussion_r4045908638
##########
fe/fe-core/src/main/java/org/apache/doris/nereids/rules/rewrite/ForeignKeyContext.java:
##########
Review Comment:
已更新注释。这里的 generic visitor 会在遍历子节点后 expire 当前节点输出中的 PK proof;Filter/Project
有专用 visitor 保留 proof,而 Join、Limit 以及其他算子会使它失效。修复见 8b5aeb392f1。
##########
fe/fe-core/src/main/java/org/apache/doris/nereids/rules/rewrite/ForeignKeyContext.java:
##########
@@ -52,7 +52,8 @@
public class ForeignKeyContext {
Set<Map<QualifiedColumn, QualifiedColumn>> constraints = new HashSet<>();
Set<QualifiedColumn> foreignKeys = new HashSet<>();
- Set<QualifiedColumn> primaryKeys = new HashSet<>();
+ Set<QualifiedColumn> declaredPrimaryKeys = new HashSet<>();
Review Comment:
是的,即使一张表只允许声明一个 PRIMARY KEY constraint,这个问题仍然存在:单个复合主键 (A, B) 原先会被扁平化成两个独立的
QualifiedColumn,从而把 A 或 B 单独当成完整主键。现在改为 Set<Set<QualifiedColumn>> /
Set<Set<Slot>>,按完整列集合激活和匹配,并补了只 join A 不消除、join A+B 才消除的测试。修复见 8b5aeb392f1。
##########
fe/fe-core/src/main/java/org/apache/doris/nereids/rules/rewrite/ForeignKeyContext.java:
##########
@@ -142,21 +143,27 @@ public boolean isForeignKey(Set<Slot> key) {
}
public boolean isPrimaryKey(Set<Slot> key) {
- return primaryKeys.containsAll(
- key.stream().map(s ->
slotToColumn.get(s)).collect(Collectors.toSet()));
+ return !key.isEmpty() && activePrimaryKeySlots.containsAll(key);
}
void putSlot(SlotReference slot, TableIf table) {
if (!slot.getOriginalColumn().isPresent()) {
return;
}
Column c = slot.getOriginalColumn().get();
- slotToColumn.put(slot, new QualifiedColumn(table, c));
+ QualifiedColumn qualifiedColumn = new QualifiedColumn(table, c);
+ slotToColumn.put(slot, qualifiedColumn);
+ if (declaredPrimaryKeys.contains(qualifiedColumn)) {
+ activePrimaryKeySlots.add(slot);
Review Comment:
已修复。对于 PARTITION/TABLET/TABLESAMPLE/direct-MV 等非完整 scan,或
skip_storage_engine_merge、增量/stream 等可能破坏唯一性的 scan,不激活 PK proof,因此不会做 join
elimination;FK constraint 元数据仍保留,供其他安全 relation instance 使用。实现同时要求 full scan
语义和 LogicalProperties 中的 uniqueness,新增了
PARTITION、TABLESAMPLE、skip_storage_engine_merge 的单测/回归。修复见 8b5aeb392f1。
##########
fe/fe-core/src/main/java/org/apache/doris/nereids/rules/rewrite/ForeignKeyContext.java:
##########
@@ -142,21 +143,27 @@ public boolean isForeignKey(Set<Slot> key) {
}
public boolean isPrimaryKey(Set<Slot> key) {
- return primaryKeys.containsAll(
- key.stream().map(s ->
slotToColumn.get(s)).collect(Collectors.toSet()));
+ return !key.isEmpty() && activePrimaryKeySlots.containsAll(key);
}
void putSlot(SlotReference slot, TableIf table) {
if (!slot.getOriginalColumn().isPresent()) {
return;
}
Column c = slot.getOriginalColumn().get();
- slotToColumn.put(slot, new QualifiedColumn(table, c));
+ QualifiedColumn qualifiedColumn = new QualifiedColumn(table, c);
+ slotToColumn.put(slot, qualifiedColumn);
+ if (declaredPrimaryKeys.contains(qualifiedColumn)) {
+ activePrimaryKeySlots.add(slot);
+ }
}
void putAlias(Slot newSlot, Slot originSlot) {
if (slotToColumn.containsKey(originSlot)) {
slotToColumn.put(newSlot, slotToColumn.get(originSlot));
+ if (activePrimaryKeySlots.contains(originSlot)) {
+ activePrimaryKeySlots.add(newSlot);
Review Comment:
同意,这个问题成立。现在每一层 alias 都会把 origin slot 的完整 predicate set 重写到 alias
slot,同时传播完整(含复合键)的 PK proof;若隐藏列上的 filter 与 FK 侧不兼容,join 会被保留。已增加 hidden-filter
alias 的单测和回归。修复见 8b5aeb392f1。
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]