diff --git a/fe/src/main/java/org/apache/doris/optimizer/OptExpression.java b/fe/src/main/java/org/apache/doris/optimizer/OptExpression.java index 8f5a12619c2b92..1b7433c1019313 100644 --- a/fe/src/main/java/org/apache/doris/optimizer/OptExpression.java +++ b/fe/src/main/java/org/apache/doris/optimizer/OptExpression.java @@ -18,10 +18,11 @@ package org.apache.doris.optimizer; import com.google.common.collect.Lists; +import org.apache.doris.optimizer.base.OptItemProperty; +import org.apache.doris.optimizer.base.OptLogicalProperty; +import org.apache.doris.optimizer.base.OptPhysicalProperty; +import org.apache.doris.optimizer.base.OptProperty; import org.apache.doris.optimizer.operator.OptOperator; -import org.apache.doris.optimizer.property.OptLogicalProperty; -import org.apache.doris.optimizer.property.OptPhysicalProperty; -import org.apache.doris.optimizer.property.OptProperty; import org.apache.doris.optimizer.stat.Statistics; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; @@ -44,11 +45,10 @@ public class OptExpression { private OptOperator op; private List inputs; - // Store where this Expression has bound from, used to + // store where this Expression has bound from, used to private MultiExpression mExpr; // Store the logical property including schema ... - private OptProperty logicalProperty; - private OptProperty physicalProperty; + private OptProperty property; private Statistics statistics; private OptExpression(OptOperator op) { @@ -78,7 +78,7 @@ private OptExpression(MultiExpression mExpr, List inputs) { private void copyPropertyAndStatistics() { this.op = mExpr.getOp(); - this.logicalProperty = mExpr.getGroup().getLogicalProperty(); + this.property = mExpr.getGroup().getLogicalProperty(); this.statistics = mExpr.getGroup().getStatistics(); } @@ -103,8 +103,10 @@ public static OptExpression createBindingInternalExpression( public int arity() { return inputs.size(); } public OptExpression getInput(int idx) { return inputs.get(idx); } public MultiExpression getMExpr() { return mExpr; } - public OptProperty getLogicalProperty() { return logicalProperty; } - public void setLogicalProperty(OptProperty property) { this.logicalProperty = property; } + public OptProperty getProperty() { return property; } + public OptLogicalProperty getLogicalProperty() { return (OptLogicalProperty) property; } + public OptItemProperty getItemProperty() { return (OptItemProperty) property; } + public OptPhysicalProperty getPhysicalProperty() { return (OptPhysicalProperty) property; } public Statistics getStatistics() { return statistics; } public void setStatistics(Statistics statistics) { this.statistics = statistics; } @@ -124,43 +126,6 @@ public boolean matchMultiExpression(MultiExpression mExpr) { return arity() == mExpr.arity(); } - private OptProperty getRightProperty() { - if (getOp().isLogical()) { - return logicalProperty; - } else if (getOp().isPhysical()) { - return physicalProperty; - } - return null; - } - - private OptProperty createRightProperty() { - if (getOp().isLogical()) { - logicalProperty = new OptLogicalProperty(); - return logicalProperty; - } else if (getOp().isPhysical()) { - physicalProperty = new OptPhysicalProperty(); - return physicalProperty; - } - return null; - } - - public OptProperty deriveProperty() { - OptProperty property = getRightProperty(); - if (property != null) { - return property; - } - // Derive children's property. - property = createRightProperty(); - final List childrenProperty = Lists.newArrayList(); - for (OptExpression expr : inputs) { - childrenProperty.add(expr.deriveProperty()); - } - // Derive current property. - final OptExpressionWapper wapper = new OptExpressionWapper(this); - property.derive(wapper, childrenProperty); - return property; - } - public void deriveStatistics() { } @@ -181,4 +146,17 @@ public String getExplainString(String headlinePrefix, String detailPrefix) { } return sb.toString(); } + + // This function will drive inputs' property first, then derive itself's + // property + public void deriveProperty() { + if (property != null) { + return; + } + for (OptExpression input : inputs) { + input.deriveProperty(); + } + property = op.createProperty(); + property.derive(this); + } } diff --git a/fe/src/main/java/org/apache/doris/optimizer/OptGroup.java b/fe/src/main/java/org/apache/doris/optimizer/OptGroup.java index f63bbd01b5fe20..bdcfb7c825be04 100644 --- a/fe/src/main/java/org/apache/doris/optimizer/OptGroup.java +++ b/fe/src/main/java/org/apache/doris/optimizer/OptGroup.java @@ -20,7 +20,7 @@ import com.google.common.base.Preconditions; import com.google.common.collect.Lists; import com.google.common.collect.Maps; -import org.apache.doris.optimizer.property.OptProperty; +import org.apache.doris.optimizer.base.OptProperty; import org.apache.doris.optimizer.search.OptimizationContext; import org.apache.doris.optimizer.stat.Statistics; import org.apache.logging.log4j.LogManager; @@ -39,12 +39,13 @@ public class OptGroup { private static int nextMExprId = 1; private GState status; private Map optContextMap; - private OptProperty logicalProperty; + private OptProperty property; private Statistics statistics; - public OptGroup(int id) { + public OptGroup(int id, OptProperty property) { this.id = id; this.status = GState.Unimplemented; + this.property = property; this.optContextMap = Maps.newHashMap(); } @@ -99,9 +100,6 @@ public MultiExpression getFirstMultiExpression() { return mExprs.get(0); } - public void deriveProperty() { - } - public int getId() { return id; } public boolean isImplemented() { return status == GState.Implemented; } public boolean isOptimized() { return status == GState.Optimized; } @@ -109,8 +107,7 @@ public void deriveProperty() { public OptimizationContext lookUp(OptimizationContext newContext) { return optContextMap.get(newContext); } public void setStatus(GState status) { this.status = status; } public GState getStatus() { return status; } - public OptProperty getLogicalProperty() { return logicalProperty; } - public void setLogicalProperty(OptProperty property) { this.logicalProperty = property; } + public OptProperty getProperty() { return property; } public Statistics getStatistics() { return statistics; } public void setStatistics(Statistics statistics) { this.statistics = statistics; } diff --git a/fe/src/main/java/org/apache/doris/optimizer/OptMemo.java b/fe/src/main/java/org/apache/doris/optimizer/OptMemo.java index 528e617aa18ed9..a38296a24766b2 100644 --- a/fe/src/main/java/org/apache/doris/optimizer/OptMemo.java +++ b/fe/src/main/java/org/apache/doris/optimizer/OptMemo.java @@ -107,13 +107,14 @@ public MultiExpression copyIn(OptGroup targetGroup, OptExpression expr, OptRuleT targetGroup.addMExpr(mExpr); return mExpr; } + // targetGroup is null, we should create new OptGroup - OptGroup newGroup = new OptGroup(nextGroupId++); + // we should derive property first to make sure expression has property + expr.deriveProperty(); + + OptGroup newGroup = new OptGroup(nextGroupId++, expr.getProperty()); newGroup.addMExpr(mExpr); groups.add(newGroup); - // Derive property - expr.deriveProperty(); - newGroup.setLogicalProperty(expr.getLogicalProperty()); return mExpr; } diff --git a/fe/src/main/java/org/apache/doris/optimizer/base/OptColumnRefSet.java b/fe/src/main/java/org/apache/doris/optimizer/base/OptColumnRefSet.java index 69a8fcda093e71..ae9d2b0ef83be2 100644 --- a/fe/src/main/java/org/apache/doris/optimizer/base/OptColumnRefSet.java +++ b/fe/src/main/java/org/apache/doris/optimizer/base/OptColumnRefSet.java @@ -30,6 +30,11 @@ public OptColumnRefSet() { bitSet = new BitSet(1024); } + public OptColumnRefSet(int id) { + bitSet = new BitSet(1024); + bitSet.set(id); + } + public OptColumnRefSet(List refs) { bitSet = new BitSet(1024); for (OptColumnRef ref : refs) { diff --git a/fe/src/main/java/org/apache/doris/optimizer/base/OptItemProperty.java b/fe/src/main/java/org/apache/doris/optimizer/base/OptItemProperty.java new file mode 100644 index 00000000000000..75f127d0ec96e5 --- /dev/null +++ b/fe/src/main/java/org/apache/doris/optimizer/base/OptItemProperty.java @@ -0,0 +1,44 @@ +// 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.optimizer.base; + +import com.google.common.base.Preconditions; +import org.apache.doris.optimizer.OptExpression; +import org.apache.doris.optimizer.operator.OptItem; + +public class OptItemProperty implements OptProperty { + private OptColumnRefSet usedColumns; + + public OptColumnRefSet getUsedColumns() { return usedColumns; } + + @Override + public void derive(OptExpression expression) { + Preconditions.checkArgument(expression.getOp() instanceof OptItem, + "op is not item, op=" + expression.getOp()); + OptItem item = (OptItem) expression.getOp(); + usedColumns = item.getUsedColumns(); + for (OptExpression input : expression.getInputs()) { + if (!input.getOp().isItem()) { + continue; + } + OptItemProperty property = (OptItemProperty) input.getProperty(); + // Include input's used columns + usedColumns.include(property.getUsedColumns()); + } + } +} diff --git a/fe/src/main/java/org/apache/doris/optimizer/property/OptLogicalProperty.java b/fe/src/main/java/org/apache/doris/optimizer/base/OptLogicalProperty.java similarity index 52% rename from fe/src/main/java/org/apache/doris/optimizer/property/OptLogicalProperty.java rename to fe/src/main/java/org/apache/doris/optimizer/base/OptLogicalProperty.java index 9b82e7e78701bf..a62134ec455e37 100644 --- a/fe/src/main/java/org/apache/doris/optimizer/property/OptLogicalProperty.java +++ b/fe/src/main/java/org/apache/doris/optimizer/base/OptLogicalProperty.java @@ -15,30 +15,19 @@ // specific language governing permissions and limitations // under the License. -package org.apache.doris.optimizer.property; +package org.apache.doris.optimizer.base; -import com.google.common.collect.Lists; -import org.apache.doris.optimizer.OptExpressionWapper; -import org.apache.doris.optimizer.base.OptColumnRef; +import org.apache.doris.optimizer.OptExpression; import org.apache.doris.optimizer.operator.OptLogical; -import java.util.List; - -public class OptLogicalProperty extends OptProperty { - - private List outputs; - - public OptLogicalProperty() { - this.outputs = Lists.newArrayList(); - } - - public List getOutputs() { return outputs; } - public void setOutputs(List columns) { outputs.addAll(columns); } +public class OptLogicalProperty implements OptProperty { + private OptColumnRefSet outputColumns; + public OptColumnRefSet getOutputColumns() { return outputColumns; } @Override - public void derive(OptExpressionWapper wapper, List childrenProperty) { - // Derive columns - final OptLogical logical = (OptLogical) wapper.getExpression().getOp(); - outputs.addAll(logical.deriveOuput(wapper)); + public void derive(OptExpression expression) { + OptLogical op = (OptLogical) expression.getOp(); + + outputColumns = op.getOutputColumns(expression); } } diff --git a/fe/src/main/java/org/apache/doris/optimizer/property/OptPhysicalProperty.java b/fe/src/main/java/org/apache/doris/optimizer/base/OptPhysicalProperty.java similarity index 75% rename from fe/src/main/java/org/apache/doris/optimizer/property/OptPhysicalProperty.java rename to fe/src/main/java/org/apache/doris/optimizer/base/OptPhysicalProperty.java index 7742ca309209c4..1fd467333ea669 100644 --- a/fe/src/main/java/org/apache/doris/optimizer/property/OptPhysicalProperty.java +++ b/fe/src/main/java/org/apache/doris/optimizer/base/OptPhysicalProperty.java @@ -15,16 +15,12 @@ // specific language governing permissions and limitations // under the License. -package org.apache.doris.optimizer.property; +package org.apache.doris.optimizer.base; -import org.apache.doris.optimizer.OptExpressionWapper; - -import java.util.List; - -public class OptPhysicalProperty extends OptProperty { +import org.apache.doris.optimizer.OptExpression; +public class OptPhysicalProperty implements OptProperty { @Override - public void derive(OptExpressionWapper wapper, List childrenProperty) { - + public void derive(OptExpression expression) { } } diff --git a/fe/src/main/java/org/apache/doris/optimizer/property/OptProperty.java b/fe/src/main/java/org/apache/doris/optimizer/base/OptProperty.java similarity index 75% rename from fe/src/main/java/org/apache/doris/optimizer/property/OptProperty.java rename to fe/src/main/java/org/apache/doris/optimizer/base/OptProperty.java index 77d2ebf457b06b..bfdd7ba8a8fe14 100644 --- a/fe/src/main/java/org/apache/doris/optimizer/property/OptProperty.java +++ b/fe/src/main/java/org/apache/doris/optimizer/base/OptProperty.java @@ -15,14 +15,10 @@ // specific language governing permissions and limitations // under the License. -package org.apache.doris.optimizer.property; +package org.apache.doris.optimizer.base; -import org.apache.doris.optimizer.OptExpressionWapper; - -import java.util.List; - -public abstract class OptProperty { - - public abstract void derive(OptExpressionWapper wapper, List childrenProperty); +import org.apache.doris.optimizer.OptExpression; +public interface OptProperty { + void derive(OptExpression expression); } diff --git a/fe/src/main/java/org/apache/doris/optimizer/operator/OptItem.java b/fe/src/main/java/org/apache/doris/optimizer/operator/OptItem.java index 8d105138096313..041a64d0047a1b 100644 --- a/fe/src/main/java/org/apache/doris/optimizer/operator/OptItem.java +++ b/fe/src/main/java/org/apache/doris/optimizer/operator/OptItem.java @@ -18,6 +18,9 @@ package org.apache.doris.optimizer.operator; import org.apache.doris.catalog.Type; +import org.apache.doris.optimizer.base.OptColumnRefSet; +import org.apache.doris.optimizer.base.OptItemProperty; +import org.apache.doris.optimizer.base.OptProperty; public abstract class OptItem extends OptOperator { protected OptItem(OptOperatorType type) { @@ -27,10 +30,18 @@ protected OptItem(OptOperatorType type) { @Override public boolean isItem() { return true; } + @Override + public OptProperty createProperty() { + return new OptItemProperty(); + } + // Scalar return value's type, every scalar has a return value, // such as compare function would return a boolean type result public abstract Type getReturnType(); public boolean isConstant() { return false; } public boolean isAlwaysTrue() { return false; } + public OptColumnRefSet getUsedColumns() { + return new OptColumnRefSet(); + } } diff --git a/fe/src/main/java/org/apache/doris/optimizer/operator/OptItemColumnRef.java b/fe/src/main/java/org/apache/doris/optimizer/operator/OptItemColumnRef.java index 4a411457348914..6aac145e1b9565 100644 --- a/fe/src/main/java/org/apache/doris/optimizer/operator/OptItemColumnRef.java +++ b/fe/src/main/java/org/apache/doris/optimizer/operator/OptItemColumnRef.java @@ -20,6 +20,7 @@ import org.apache.doris.catalog.Type; import org.apache.doris.optimizer.OptUtils; import org.apache.doris.optimizer.base.OptColumnRef; +import org.apache.doris.optimizer.base.OptColumnRefSet; // Reference to a column public class OptItemColumnRef extends OptItem { @@ -55,4 +56,9 @@ public String getExplainString(String prefix) { sb.append(prefix).append("ItemColumnRef(ref=").append(ref).append(")"); return sb.toString(); } + + @Override + public OptColumnRefSet getUsedColumns() { + return new OptColumnRefSet(ref.getId()); + } } diff --git a/fe/src/main/java/org/apache/doris/optimizer/operator/OptLogical.java b/fe/src/main/java/org/apache/doris/optimizer/operator/OptLogical.java index 6e0ac7771b650d..b6cd91bff6d9d7 100644 --- a/fe/src/main/java/org/apache/doris/optimizer/operator/OptLogical.java +++ b/fe/src/main/java/org/apache/doris/optimizer/operator/OptLogical.java @@ -17,16 +17,15 @@ package org.apache.doris.optimizer.operator; -import com.google.common.collect.Lists; import org.apache.doris.optimizer.OptExpression; import org.apache.doris.optimizer.OptExpressionWapper; -import org.apache.doris.optimizer.base.OptColumnRef; -import org.apache.doris.optimizer.property.OptLogicalProperty; +import org.apache.doris.optimizer.base.OptColumnRefSet; +import org.apache.doris.optimizer.base.OptLogicalProperty; +import org.apache.doris.optimizer.base.OptProperty; import org.apache.doris.optimizer.stat.Statistics; import org.apache.doris.optimizer.stat.StatisticsContext; import java.util.BitSet; -import java.util.List; public abstract class OptLogical extends OptOperator { @@ -38,17 +37,18 @@ protected OptLogical(OptOperatorType type) { public abstract BitSet getCandidateRulesForImplement(); - public List deriveOuput(OptExpressionWapper wapper) { - final List results = Lists.newArrayList(); - for (OptExpression expression : wapper.getExpression().getInputs()) { - final OptLogicalProperty property = (OptLogicalProperty)expression.getLogicalProperty(); - results.addAll(property.getOutputs()); - } - return results; - } - public abstract Statistics deriveStat(OptExpressionWapper wapper, StatisticsContext context); @Override public boolean isLogical() { return true; } + + @Override + public OptProperty createProperty() { + return new OptLogicalProperty(); + } + + // TODO(zc): returning null to make compiler happy + public OptColumnRefSet getOutputColumns(OptExpression expression) { + return null; + } } diff --git a/fe/src/main/java/org/apache/doris/optimizer/operator/OptLogicalAggregate.java b/fe/src/main/java/org/apache/doris/optimizer/operator/OptLogicalAggregate.java index 2e113f9baec635..1e4c2316f1bc37 100644 --- a/fe/src/main/java/org/apache/doris/optimizer/operator/OptLogicalAggregate.java +++ b/fe/src/main/java/org/apache/doris/optimizer/operator/OptLogicalAggregate.java @@ -17,7 +17,9 @@ package org.apache.doris.optimizer.operator; +import org.apache.doris.optimizer.OptExpression; import org.apache.doris.optimizer.OptExpressionWapper; +import org.apache.doris.optimizer.base.OptColumnRefSet; import org.apache.doris.optimizer.rule.OptRule; import org.apache.doris.optimizer.stat.Statistics; import org.apache.doris.optimizer.stat.StatisticsContext; @@ -41,8 +43,15 @@ public BitSet getCandidateRulesForImplement() { return null; } + @Override + public OptColumnRefSet getOutputColumns(OptExpression expression) { + return expression.getLogicalProperty().getOutputColumns(); + } + @Override public Statistics deriveStat(OptExpressionWapper wapper, StatisticsContext context) { return null; } + + } diff --git a/fe/src/main/java/org/apache/doris/optimizer/operator/OptLogicalScan.java b/fe/src/main/java/org/apache/doris/optimizer/operator/OptLogicalScan.java index 81df94e68bcc91..f9cbd4a26a084a 100644 --- a/fe/src/main/java/org/apache/doris/optimizer/operator/OptLogicalScan.java +++ b/fe/src/main/java/org/apache/doris/optimizer/operator/OptLogicalScan.java @@ -22,8 +22,10 @@ import org.apache.doris.analysis.SlotDescriptor; import org.apache.doris.catalog.OlapTable; import org.apache.doris.catalog.Table; +import org.apache.doris.optimizer.OptExpression; import org.apache.doris.optimizer.OptExpressionWapper; import org.apache.doris.optimizer.base.OptColumnRef; +import org.apache.doris.optimizer.base.OptColumnRefSet; import org.apache.doris.optimizer.rule.OptRuleType; import org.apache.doris.optimizer.stat.DefaultStatistics; import org.apache.doris.optimizer.stat.Statistics; @@ -68,8 +70,8 @@ public BitSet getCandidateRulesForImplement() { } @Override - public List deriveOuput(OptExpressionWapper wapper) { - return outputs; + public OptColumnRefSet getOutputColumns(OptExpression expression) { + return new OptColumnRefSet(outputs); } @Override diff --git a/fe/src/main/java/org/apache/doris/optimizer/operator/OptLogicalUnion.java b/fe/src/main/java/org/apache/doris/optimizer/operator/OptLogicalUnion.java index 0c6e73c860858f..568037e6b4fd1d 100644 --- a/fe/src/main/java/org/apache/doris/optimizer/operator/OptLogicalUnion.java +++ b/fe/src/main/java/org/apache/doris/optimizer/operator/OptLogicalUnion.java @@ -17,7 +17,9 @@ package org.apache.doris.optimizer.operator; +import org.apache.doris.optimizer.OptExpression; import org.apache.doris.optimizer.OptExpressionWapper; +import org.apache.doris.optimizer.base.OptColumnRefSet; import org.apache.doris.optimizer.stat.Statistics; import org.apache.doris.optimizer.stat.StatisticsContext; @@ -39,6 +41,15 @@ public BitSet getCandidateRulesForImplement() { return null; } + @Override + public OptColumnRefSet getOutputColumns(OptExpression expression) { + OptColumnRefSet columns = new OptColumnRefSet(); + for (OptExpression input : expression.getInputs()) { + columns.include(input.getLogicalProperty().getOutputColumns()); + } + return columns; + } + @Override public Statistics deriveStat(OptExpressionWapper wapper, StatisticsContext context) { return null; diff --git a/fe/src/main/java/org/apache/doris/optimizer/operator/OptLogicallJoin.java b/fe/src/main/java/org/apache/doris/optimizer/operator/OptLogicallJoin.java index a17dfe364e813c..423c701cc693d8 100644 --- a/fe/src/main/java/org/apache/doris/optimizer/operator/OptLogicallJoin.java +++ b/fe/src/main/java/org/apache/doris/optimizer/operator/OptLogicallJoin.java @@ -18,7 +18,10 @@ package org.apache.doris.optimizer.operator; import org.apache.doris.analysis.JoinOperator; +import org.apache.doris.optimizer.OptExpression; import org.apache.doris.optimizer.OptExpressionWapper; +import org.apache.doris.optimizer.base.OptColumnRefSet; +import org.apache.doris.optimizer.base.OptLogicalProperty; import org.apache.doris.optimizer.rule.OptRuleType; import org.apache.doris.optimizer.stat.DefaultStatistics; import org.apache.doris.optimizer.stat.RowCountProvider; @@ -50,6 +53,15 @@ public BitSet getCandidateRulesForImplement() { return set; } + @Override + public OptColumnRefSet getOutputColumns(OptExpression expression) { + OptColumnRefSet columns = new OptColumnRefSet(); + for (int i = 0; i < 2; ++i) { + columns.include(expression.getInput(i).getLogicalProperty().getOutputColumns()); + } + return columns; + } + @Override public Statistics deriveStat(OptExpressionWapper wapper, StatisticsContext context) { final Statistics joinStatistics = diff --git a/fe/src/main/java/org/apache/doris/optimizer/operator/OptOperator.java b/fe/src/main/java/org/apache/doris/optimizer/operator/OptOperator.java index de73fe8b4e6008..7b24bd18e4fa1c 100644 --- a/fe/src/main/java/org/apache/doris/optimizer/operator/OptOperator.java +++ b/fe/src/main/java/org/apache/doris/optimizer/operator/OptOperator.java @@ -17,6 +17,9 @@ package org.apache.doris.optimizer.operator; +import com.google.common.base.Preconditions; +import org.apache.doris.optimizer.base.OptProperty; + // Base class for operation. Operation can be logical or physical // Pattern is a special kind of operation which is only used in rules to // match pattern and then do transform @@ -56,6 +59,13 @@ public String getExplainString(String prefix) { return type.getName(); } + // Create property for this operator. A item operator would create OptItemProperty + // and a logical operator would create OptLogicalProperty + public OptProperty createProperty() { + Preconditions.checkArgument(false, "this should not be called, op=" + this); + return null; + } + @Override public int hashCode() { return type.hashCode(); diff --git a/fe/src/main/java/org/apache/doris/optimizer/operator/OptPhysical.java b/fe/src/main/java/org/apache/doris/optimizer/operator/OptPhysical.java index b5ecc7a3700249..8d0e15580e75fa 100644 --- a/fe/src/main/java/org/apache/doris/optimizer/operator/OptPhysical.java +++ b/fe/src/main/java/org/apache/doris/optimizer/operator/OptPhysical.java @@ -17,6 +17,9 @@ package org.apache.doris.optimizer.operator; +import org.apache.doris.optimizer.base.OptPhysicalProperty; +import org.apache.doris.optimizer.base.OptProperty; + public abstract class OptPhysical extends OptOperator { protected OptPhysical(OptOperatorType type) { @@ -25,4 +28,8 @@ protected OptPhysical(OptOperatorType type) { @Override public boolean isPhysical() { return true; } + @Override + public OptProperty createProperty() { + return new OptPhysicalProperty(); + } }