diff --git a/fe/fe-core/src/main/java/com/starrocks/catalog/ComplexTypeAccessGroup.java b/fe/fe-core/src/main/java/com/starrocks/catalog/ComplexTypeAccessGroup.java index ba4a2b3988085..f10cd5d5a0a3d 100644 --- a/fe/fe-core/src/main/java/com/starrocks/catalog/ComplexTypeAccessGroup.java +++ b/fe/fe-core/src/main/java/com/starrocks/catalog/ComplexTypeAccessGroup.java @@ -14,25 +14,19 @@ package com.starrocks.catalog; -import java.util.ArrayList; -import java.util.List; +import java.util.HashSet; +import java.util.Set; +// Record ColumnRefOperator's each ComplexTypeAccessPaths +// We have to use HashSet to deduplicate same ComplexTypeAccessPaths, it can avoid oom problem public class ComplexTypeAccessGroup { - private final List accessPaths = new ArrayList<>(); - - public int size() { - return accessPaths.size(); - } - - public ComplexTypeAccessPaths get(int idx) { - return accessPaths.get(idx); - } + private final Set accessPaths = new HashSet<>(); public void addAccessPaths(ComplexTypeAccessPaths complexTypeAccessPaths) { accessPaths.add(complexTypeAccessPaths); } - public List getAccessGroup() { + public Set getAccessGroup() { return accessPaths; } } diff --git a/fe/fe-core/src/main/java/com/starrocks/catalog/ComplexTypeAccessPath.java b/fe/fe-core/src/main/java/com/starrocks/catalog/ComplexTypeAccessPath.java index afea5f022c4fa..ba858d73fa502 100644 --- a/fe/fe-core/src/main/java/com/starrocks/catalog/ComplexTypeAccessPath.java +++ b/fe/fe-core/src/main/java/com/starrocks/catalog/ComplexTypeAccessPath.java @@ -14,6 +14,8 @@ package com.starrocks.catalog; +import java.util.Objects; + public class ComplexTypeAccessPath { private final ComplexTypeAccessPathType accessPathType; @@ -36,4 +38,25 @@ public ComplexTypeAccessPathType getAccessPathType() { public String getStructSubfieldName() { return this.structSubfieldName; } + + @Override + public final boolean equals(Object o) { + if (this == o) { + return true; + } + if (!(o instanceof ComplexTypeAccessPath)) { + return false; + } + + ComplexTypeAccessPath that = (ComplexTypeAccessPath) o; + return accessPathType == that.accessPathType && + Objects.equals(structSubfieldName, that.structSubfieldName); + } + + @Override + public int hashCode() { + int result = Objects.hashCode(accessPathType); + result = 31 * result + Objects.hashCode(structSubfieldName); + return result; + } } diff --git a/fe/fe-core/src/main/java/com/starrocks/catalog/ComplexTypeAccessPaths.java b/fe/fe-core/src/main/java/com/starrocks/catalog/ComplexTypeAccessPaths.java index cf4bfc140d684..aaab0ace78b7b 100644 --- a/fe/fe-core/src/main/java/com/starrocks/catalog/ComplexTypeAccessPaths.java +++ b/fe/fe-core/src/main/java/com/starrocks/catalog/ComplexTypeAccessPaths.java @@ -14,12 +14,16 @@ package com.starrocks.catalog; +import com.google.common.base.Preconditions; import com.google.common.collect.ImmutableList; +import java.util.Objects; + public class ComplexTypeAccessPaths { private final ImmutableList accessPaths; public ComplexTypeAccessPaths(ImmutableList accessPaths) { + Preconditions.checkNotNull(accessPaths, "accessPaths can't be null"); this.accessPaths = accessPaths; } @@ -38,4 +42,22 @@ public boolean isEmpty() { public ImmutableList getAccessPaths() { return accessPaths; } + + @Override + public final boolean equals(Object o) { + if (this == o) { + return true; + } + if (!(o instanceof ComplexTypeAccessPaths)) { + return false; + } + + ComplexTypeAccessPaths that = (ComplexTypeAccessPaths) o; + return Objects.equals(accessPaths, that.accessPaths); + } + + @Override + public int hashCode() { + return Objects.hashCode(accessPaths); + } } diff --git a/fe/fe-core/src/main/java/com/starrocks/sql/optimizer/rule/tree/PruneComplexTypeUtil.java b/fe/fe-core/src/main/java/com/starrocks/sql/optimizer/rule/tree/PruneComplexTypeUtil.java index ff53dfb7270fe..f11732a8258f6 100644 --- a/fe/fe-core/src/main/java/com/starrocks/sql/optimizer/rule/tree/PruneComplexTypeUtil.java +++ b/fe/fe-core/src/main/java/com/starrocks/sql/optimizer/rule/tree/PruneComplexTypeUtil.java @@ -83,10 +83,11 @@ public void addAccessPaths(ColumnRefOperator columnRefOperator, ComplexTypeAcces public void addAccessPaths(ColumnRefOperator columnRefOperator, ComplexTypeAccessPaths curAccessPaths, ComplexTypeAccessGroup visitedAccessGroup) { - int size = visitedAccessGroup.size(); - // We should we below loop to avoid ConcurrentModificationException - for (int i = 0; i < size; i++) { - addAccessPaths(columnRefOperator, concatAccessPaths(curAccessPaths, visitedAccessGroup.get(i))); + // We should copy it first to avoid ConcurrentModificationException + ImmutableList accessGroup = ImmutableList.builder().addAll( + visitedAccessGroup.getAccessGroup()).build(); + for (ComplexTypeAccessPaths complexTypeAccessPaths : accessGroup) { + addAccessPaths(columnRefOperator, concatAccessPaths(curAccessPaths, complexTypeAccessPaths)); } }