morrySnow commented on code in PR #27051:
URL: https://github.com/apache/doris/pull/27051#discussion_r1401606207


##########
fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/NamedExpression.java:
##########
@@ -33,6 +33,7 @@ protected NamedExpression(List<Expression> children) {
     }
 
     public Slot toSlot() throws UnboundException {
+

Review Comment:
   remove this blank line



##########
fe/fe-core/src/main/java/org/apache/doris/nereids/properties/FunctionalDependencies.java:
##########
@@ -0,0 +1,174 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+package org.apache.doris.nereids.properties;
+
+import org.apache.doris.nereids.trees.expressions.Slot;
+
+import com.google.common.collect.ImmutableSet;
+
+import java.util.HashSet;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+/**
+ * Record functional dependencies

Review Comment:
   add more comment to explain what types of FDS do we have



##########
fe/fe-core/src/main/java/org/apache/doris/nereids/properties/FunctionalDependencies.java:
##########
@@ -0,0 +1,174 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+package org.apache.doris.nereids.properties;
+
+import org.apache.doris.nereids.trees.expressions.Slot;
+
+import com.google.common.collect.ImmutableSet;
+
+import java.util.HashSet;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+/**
+ * Record functional dependencies
+ */
+public class FunctionalDependencies {
+    NestedSet uniqueSet = new NestedSet();
+    NestedSet uniformSet = new NestedSet();

Review Comment:
   private final?



##########
fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/logical/LogicalExcept.java:
##########
@@ -34,7 +35,7 @@
 /**
  * Logical Except.
  */
-public class LogicalExcept extends LogicalSetOperation {
+public class LogicalExcept extends LogicalSetOperation implements PropagateFD {

Review Comment:
   why not add all columns as a unique cluster into FD?



##########
fe/fe-core/src/main/java/org/apache/doris/nereids/properties/FunctionalDependencies.java:
##########
@@ -0,0 +1,174 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+package org.apache.doris.nereids.properties;
+
+import org.apache.doris.nereids.trees.expressions.Slot;
+
+import com.google.common.collect.ImmutableSet;
+
+import java.util.HashSet;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+/**
+ * Record functional dependencies
+ */
+public class FunctionalDependencies {
+    NestedSet uniqueSet = new NestedSet();
+    NestedSet uniformSet = new NestedSet();
+
+    public FunctionalDependencies() {}
+
+    public FunctionalDependencies(FunctionalDependencies other) {
+        this.uniformSet = new NestedSet(other.uniformSet);
+        this.uniqueSet = new NestedSet(other.uniqueSet);
+    }
+
+    public void addUniformSlot(Slot slot) {
+        uniformSet.add(slot);
+    }
+
+    public void addUniformSlot(FunctionalDependencies functionalDependencies) {
+        uniformSet.add(functionalDependencies.uniformSet);
+    }
+
+    public void addUniformSlot(ImmutableSet<Slot> slotSet) {
+        uniformSet.add(slotSet);
+    }
+
+    public boolean isEmpty() {
+        return uniformSet.isEmpty() && uniqueSet.isEmpty();
+    }
+
+    public void pruneSlots(Set<Slot> outputSlots) {
+        uniformSet.removeNotContain(outputSlots);
+        uniqueSet.removeNotContain(outputSlots);
+    }
+
+    public void addUniqueSlot(Slot slot) {
+        uniqueSet.add(slot);
+    }
+
+    public void addUniqueSlot(ImmutableSet<Slot> slotSet) {
+        uniqueSet.add(slotSet);
+    }
+
+    public boolean isUnique(Slot slot) {
+        return uniqueSet.contains(slot);
+    }
+
+    public boolean isUnique(Set<Slot> slotSet) {
+        if (slotSet.isEmpty()) {
+            return false;
+        }
+        return uniqueSet.containsAnySub(slotSet);
+    }
+
+    public boolean isUniform(Slot slot) {
+        return uniformSet.contains(slot);
+    }
+
+    public boolean isUniform(ImmutableSet<Slot> slotSet) {
+        return uniformSet.contains(slotSet) || 
slotSet.stream().allMatch(uniformSet::contains);
+    }
+
+    public void addFunctionalDependencies(FunctionalDependencies fd) {
+        uniformSet.add(fd.uniformSet);
+        uniqueSet.add(fd.uniqueSet);
+    }
+
+    @Override
+    public String toString() {
+        return "uniform:" + uniformSet.toString()
+                + "\t unique:" + uniqueSet.toString();
+    }
+
+    class NestedSet {
+        Set<Slot> slots = new HashSet<>();
+        Set<ImmutableSet<Slot>> slotSets = new HashSet<>();

Review Comment:
   it it better to use immutable data structure



##########
fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/logical/LogicalRepeat.java:
##########
@@ -41,7 +42,7 @@
  * LogicalRepeat.
  */
 public class LogicalRepeat<CHILD_TYPE extends Plan> extends 
LogicalUnary<CHILD_TYPE>
-        implements Repeat<CHILD_TYPE> {
+        implements Repeat<CHILD_TYPE>, BlockFD {

Review Comment:
   some uniform could be reserved



##########
fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/BlockFD.java:
##########
@@ -0,0 +1,34 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+package org.apache.doris.nereids.trees.plans;
+
+import org.apache.doris.nereids.properties.FunctionalDependencies;
+import org.apache.doris.nereids.trees.expressions.Slot;
+import org.apache.doris.nereids.trees.plans.logical.LogicalPlan;
+
+import java.util.List;
+
+/**
+ * Block fd
+ */
+public interface BlockFD extends LogicalPlan {

Review Comment:
   add more comment on this class to explain where the name `block` come from 
and what's mean



##########
fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/logical/LogicalAggregate.java:
##########
@@ -282,4 +290,69 @@ public LogicalAggregate<Plan> 
withNormalized(List<Expression> normalizedGroupBy,
         return new LogicalAggregate<>(normalizedGroupBy, normalizedOutput, 
true, ordinalIsResolved, generated,
                 hasPushed, sourceRepeat, Optional.empty(), Optional.empty(), 
normalizedChild);
     }
+
+    private void updateByAggregateFunctionn(NamedExpression namedExpression, 
FunctionalDependencies fd) {

Review Comment:
   typo
   ```suggestion
       private void updateByAggregateFunction(NamedExpression namedExpression, 
FunctionalDependencies fd) {
   ```



##########
fe/fe-core/src/main/java/org/apache/doris/nereids/properties/FunctionalDependencies.java:
##########
@@ -0,0 +1,174 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+package org.apache.doris.nereids.properties;
+
+import org.apache.doris.nereids.trees.expressions.Slot;
+
+import com.google.common.collect.ImmutableSet;
+
+import java.util.HashSet;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+/**
+ * Record functional dependencies
+ */
+public class FunctionalDependencies {

Review Comment:
   should override hashCode and equals?



##########
fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/PropagateFD.java:
##########
@@ -0,0 +1,43 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+package org.apache.doris.nereids.trees.plans;
+
+import org.apache.doris.nereids.properties.FunctionalDependencies;
+import org.apache.doris.nereids.trees.expressions.Slot;
+import org.apache.doris.nereids.trees.plans.logical.LogicalPlan;
+
+import java.util.List;
+
+/**
+ * Propage fd
+ */
+public interface PropagateFD extends LogicalPlan {

Review Comment:
   same as blockFD



##########
fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/logical/LogicalAggregate.java:
##########
@@ -282,4 +290,69 @@ public LogicalAggregate<Plan> 
withNormalized(List<Expression> normalizedGroupBy,
         return new LogicalAggregate<>(normalizedGroupBy, normalizedOutput, 
true, ordinalIsResolved, generated,
                 hasPushed, sourceRepeat, Optional.empty(), Optional.empty(), 
normalizedChild);
     }
+
+    private void updateByAggregateFunctionn(NamedExpression namedExpression, 
FunctionalDependencies fd) {
+        if (namedExpression instanceof Slot) {
+            fd.addUniqueSlot(namedExpression.toSlot());
+            return;
+        }
+
+        if (!(namedExpression instanceof Alias && namedExpression.child(0) 
instanceof AggregateFunction)) {
+            return;
+        }
+
+        AggregateFunction agg = (AggregateFunction) namedExpression.child(0);
+        if (agg instanceof Count || agg instanceof Ndv) {
+            fd.addUniformSlot(namedExpression.toSlot());
+            return;
+        }
+
+        if (ExpressionUtils.isInjectiveAgg(agg)
+                && 
child().getLogicalProperties().getFunctionalDependencies().isUnique(agg.getInputSlots()))
 {
+            fd.addUniqueSlot(namedExpression.toSlot());
+        }
+    }
+
+    @Override
+    public FunctionalDependencies computeFD(List<Slot> outputs) {

Review Comment:
   i think it is better use full name rather than acronym



##########
fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/logical/LogicalJoin.java:
##########
@@ -357,6 +362,90 @@ public LogicalJoin<Plan, Plan> 
withOtherJoinConjuncts(List<Expression> otherJoin
                 markJoinSlotReference, children);
     }
 
+    private @Nullable Pair<Set<Slot>, Set<Slot>> extractHashKeys() {
+        Set<Slot> leftKeys = new HashSet<>();
+        Set<Slot> rightKeys = new HashSet<>();
+        for (Expression expression : hashJoinConjuncts) {
+            if (!(expression instanceof EqualTo

Review Comment:
   should we need to think about null safe equal when left and right are both 
not null?



##########
fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/logical/LogicalGenerate.java:
##########
@@ -39,7 +40,7 @@
 /**
  * plan for table generator, the statement like: SELECT * FROM tbl LATERAL 
VIEW EXPLODE(c1) g as (gc1);
  */
-public class LogicalGenerate<CHILD_TYPE extends Plan> extends 
LogicalUnary<CHILD_TYPE> implements Generate {
+public class LogicalGenerate<CHILD_TYPE extends Plan> extends 
LogicalUnary<CHILD_TYPE> implements Generate, BlockFD {

Review Comment:
   i think uniform still working after generate



##########
fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/logical/LogicalLimit.java:
##########
@@ -140,4 +141,14 @@ public LogicalLimit<Plan> withChildren(List<Plan> 
children) {
         Preconditions.checkArgument(children.size() == 1);
         return new LogicalLimit<>(limit, offset, phase, children.get(0));
     }
+
+    @Override
+    public FunctionalDependencies computeFD(List<Slot> outputs) {
+        FunctionalDependencies functionalDependencies = new 
FunctionalDependencies(
+                child(0).getLogicalProperties().getFunctionalDependencies());
+        if (getLimit() == 1) {
+            outputs.forEach(functionalDependencies::addUniformSlot);

Review Comment:
   need to add to unique?



##########
fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/logical/LogicalSubQueryAlias.java:
##########
@@ -39,7 +40,7 @@
  *
  * @param <CHILD_TYPE> param
  */
-public class LogicalSubQueryAlias<CHILD_TYPE extends Plan> extends 
LogicalUnary<CHILD_TYPE> {
+public class LogicalSubQueryAlias<CHILD_TYPE extends Plan> extends 
LogicalUnary<CHILD_TYPE> implements PropagateFD {

Review Comment:
   after LogicalSubQueryAlias, the slot expr id of output slots changed, so 
need computeFD?



##########
fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/logical/LogicalTopN.java:
##########
@@ -148,4 +149,14 @@ public Plan 
withGroupExprLogicalPropChildren(Optional<GroupExpression> groupExpr
         Preconditions.checkArgument(children.size() == 1);
         return new LogicalTopN<>(orderKeys, limit, offset, groupExpression, 
logicalProperties, children.get(0));
     }
+
+    @Override
+    public FunctionalDependencies computeFD(List<Slot> outputs) {
+        FunctionalDependencies functionalDependencies = new 
FunctionalDependencies(
+                child(0).getLogicalProperties().getFunctionalDependencies());
+        if (getLimit() == 1) {
+            outputs.forEach(functionalDependencies::addUniformSlot);

Review Comment:
   same as limit



##########
fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/logical/LogicalProject.java:
##########
@@ -200,4 +203,17 @@ public JSONObject toJson() {
         logicalProject.put("Properties", properties);
         return logicalProject;
     }
+
+    @Override
+    public FunctionalDependencies computeFD(List<Slot> outputs) {
+        FunctionalDependencies fd = new FunctionalDependencies(
+                child().getLogicalProperties().getFunctionalDependencies());
+        fd.pruneSlots(new HashSet<>(outputs));
+        for (NamedExpression proj : projects) {
+            if (proj instanceof Alias && proj.child(0).isConstant()) {
+                fd.addUniformSlot(proj.toSlot());
+            }
+        }

Review Comment:
   maybe we should consider `uuid()` as unique?



-- 
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: commits-unsubscr...@doris.apache.org

For queries about this service, please contact Infrastructure at:
us...@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscr...@doris.apache.org
For additional commands, e-mail: commits-h...@doris.apache.org

Reply via email to