diff --git a/fe/src/main/java/org/apache/doris/analysis/CaseWhenClause.java b/fe/src/main/java/org/apache/doris/analysis/CaseWhenClause.java index 3a68ce296f4485..c07bd8d79e3bb7 100644 --- a/fe/src/main/java/org/apache/doris/analysis/CaseWhenClause.java +++ b/fe/src/main/java/org/apache/doris/analysis/CaseWhenClause.java @@ -21,7 +21,7 @@ /** * captures info of a single WHEN expr THEN expr clause. */ -class CaseWhenClause { +public class CaseWhenClause { private final Expr whenExpr; private final Expr thenExpr; diff --git a/fe/src/main/java/org/apache/doris/optimizer/ExpressionToStmtConverter.java b/fe/src/main/java/org/apache/doris/optimizer/ExpressionToStmtConverter.java new file mode 100644 index 00000000000000..0bd5b6bc3dc6c0 --- /dev/null +++ b/fe/src/main/java/org/apache/doris/optimizer/ExpressionToStmtConverter.java @@ -0,0 +1,225 @@ +// 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; + +import com.google.common.collect.Lists; +import org.apache.doris.analysis.ArithmeticExpr; +import org.apache.doris.analysis.BinaryPredicate; +import org.apache.doris.analysis.CaseExpr; +import org.apache.doris.analysis.CaseWhenClause; +import org.apache.doris.analysis.CastExpr; +import org.apache.doris.analysis.CompoundPredicate; +import org.apache.doris.analysis.Expr; +import org.apache.doris.analysis.FunctionCallExpr; +import org.apache.doris.analysis.InPredicate; +import org.apache.doris.analysis.IsNullPredicate; +import org.apache.doris.analysis.LikePredicate; +import org.apache.doris.analysis.SlotDescriptor; +import org.apache.doris.analysis.SlotRef; +import org.apache.doris.common.UserException; +import org.apache.doris.optimizer.operator.OptItemArithmetic; +import org.apache.doris.optimizer.operator.OptItemBinaryPredicate; +import org.apache.doris.optimizer.operator.OptItemCase; +import org.apache.doris.optimizer.operator.OptItemCast; +import org.apache.doris.optimizer.operator.OptItemColumnRef; +import org.apache.doris.optimizer.operator.OptItemCompoundPredicate; +import org.apache.doris.optimizer.operator.OptItemConst; +import org.apache.doris.optimizer.operator.OptItemFunctionCall; +import org.apache.doris.optimizer.operator.OptItemInPredicate; +import org.apache.doris.optimizer.operator.OptItemIsNullPredicate; +import org.apache.doris.optimizer.operator.OptItemLikePredicate; +import org.apache.doris.optimizer.operator.OptOperator; +import org.apache.doris.optimizer.operator.OptPhysicalMysqlScan; +import org.apache.doris.planner.MysqlScanNode; +import org.apache.doris.planner.PlanNode; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +import java.util.List; + +// Convert expression to statement, used to convert optimized expression +// to a plan tree +public class ExpressionToStmtConverter { + private static final Logger LOG = LogManager.getLogger(ExpressionToStmtConverter.class); + + private OptConverterCtx ctx; + + public ExpressionToStmtConverter(OptConverterCtx ctx) { + this.ctx = ctx; + } + + public PlanNode convertPhysical(OptExpression expr) { + OptOperator op = expr.getOp(); + switch (op.getType()) { + case OP_PHYSICAL_MYSQL_SCAN: + return convertMysqlScan(expr) + } + return null; + } + + public MysqlScanNode convertMysqlScan(OptExpression expr) { + OptPhysicalMysqlScan scanOp = (OptPhysicalMysqlScan) expr.getOp(); + MysqlScanNode node = new MysqlScanNode() + return null; + } + + public Expr convertItem(OptExpression expr) throws UserException { + OptOperator op = expr.getOp(); + switch (op.getType()) { + case OP_ITEM_BINARY_PREDICATE: + return convertBinaryPred(expr); + case OP_ITEM_COMPOUND_PREDICATE: + return convertCompoundPred(expr); + case OP_ITEM_CONST: + return convertConst(expr); + case OP_ITEM_ARITHMETIC: + return convertArithmetic(expr); + case OP_ITEM_CASE: + return convertCase(expr); + case OP_ITEM_CAST: + return convertCast(expr); + case OP_ITEM_FUNCTION_CALL: + return convertFunctionCall(expr); + case OP_ITEM_AGG_FUNC: + return convertAggregateFunction(expr); + case OP_ITEM_COLUMN_REF: + return convertColumnRef(expr); + case OP_ITEM_IN_PREDICATE: + return convertInPred(expr); + case OP_ITEM_LIKE_PREDICATE: + return convertLikePred(expr); + case OP_ITEM_IS_NULL_PREDICATE: + return convertIsNullPred(expr); + } + } + + private Expr convertConst(OptExpression expr) { + return ((OptItemConst) expr.getOp()).getLiteral(); + } + + private Expr convertIsNullPred(OptExpression expr) throws UserException { + Expr child = convertItem(expr.getInput(0)); + OptItemIsNullPredicate pred = (OptItemIsNullPredicate) expr.getOp(); + return new IsNullPredicate(child, pred.isNotNull()); + } + + private Expr convertLikePred(OptExpression expr) throws UserException { + Expr leftChild = convertItem(expr.getInput(0)); + Expr rightChild = convertItem(expr.getInput(0)); + OptItemLikePredicate pred = (OptItemLikePredicate) expr.getOp(); + return new LikePredicate(pred.getOp(), leftChild, rightChild); + } + + private Expr convertInPred(OptExpression expr) throws UserException { + Expr compareChild = convertItem(expr.getInput(0)); + + List children = Lists.newArrayList(); + for (int i = 1; i < expr.getInputs().size(); ++i) { + children.add(convertItem(expr.getInput(i))); + } + + OptItemInPredicate pred = (OptItemInPredicate) expr.getOp(); + return new InPredicate(compareChild, children, pred.isNotIn()); + } + + private Expr convertColumnRef(OptExpression expr) throws UserException { + OptItemColumnRef columnRef = (OptItemColumnRef) expr.getOp(); + SlotDescriptor slotDesc = ctx.getSlotRef(columnRef.getRef().getId()); + if (slotDesc == null) { + LOG.warn("fail to get SlotRef with ColumnRef, columnRef={}", columnRef.getRef()); + throw new UserException("Unknown column reference"); + } + return new SlotRef(slotDesc); + } + + private Expr convertAggregateFunction(OptExpression expr) { + return null; + } + + private Expr convertCast(OptExpression expr) throws UserException { + Expr child = convertItem(expr.getInput(0)); + OptItemCast op = (OptItemCast) expr.getOp(); + return new CastExpr(op.getDestType(), child); + } + + private Expr convertCase(OptExpression expr) throws UserException { + OptItemCase caseOp = (OptItemCase) expr.getOp(); + Expr caseExpr = null; + int idx = 0; + if (caseOp.hasCase()) { + caseExpr = convertItem(expr.getInput(idx)); + idx++; + } + int endIdx = expr.getInputs().size(); + Expr elseExpr = null; + if (caseOp.hasElse()) { + endIdx--; + elseExpr = convertItem(expr.getInput(endIdx)); + } + if ((endIdx - idx) % 2 != 0) { + throw new UserException(""); + } + List whenThenList = Lists.newArrayList(); + for (; idx < endIdx; idx += 2) { + Expr whenExpr = convertItem(expr.getInput(idx)); + Expr thenExpr = convertItem(expr.getInput(idx + 1)); + whenThenList.add(new CaseWhenClause(whenExpr, thenExpr)); + } + + return new CaseExpr(caseExpr, whenThenList, elseExpr); + } + + private Expr convertArithmetic(OptExpression expr) throws UserException { + Expr leftChild = convertItem(expr.getInput(0)); + Expr rightChild = null; + if (expr.getInputs().size() == 2) { + rightChild = convertItem(expr.getInput(1)); + } + OptItemArithmetic item = (OptItemArithmetic) expr.getOp(); + return new ArithmeticExpr(item.getOp(), leftChild, rightChild); + } + + private Expr convertBinaryPred(OptExpression expr) throws UserException { + Expr leftChild = convertItem(expr.getInput(0)); + Expr rightChild = convertItem(expr.getInput(1)); + + OptItemBinaryPredicate pred = (OptItemBinaryPredicate) expr.getOp(); + return new BinaryPredicate(pred.getOp(), leftChild, rightChild); + } + + private Expr convertCompoundPred(OptExpression expr) throws UserException { + OptItemCompoundPredicate pred = (OptItemCompoundPredicate) expr.getOp(); + Expr leftChild = convertItem(expr.getInput(0)); + Expr rightChild = null; + if (pred.getOp() != CompoundPredicate.Operator.NOT) { + rightChild = convertItem(expr.getInput(1)); + } + return new CompoundPredicate(pred.getOp(), leftChild, rightChild); + } + + private Expr convertFunctionCall(OptExpression expr) throws UserException { + OptItemFunctionCall funcOp = (OptItemFunctionCall) expr.getOp(); + + List children = Lists.newArrayList(); + for (OptExpression input : expr.getInputs()) { + children.add(convertItem(input)); + } + + return new FunctionCallExpr(funcOp.getName(), children); + } +} diff --git a/fe/src/main/java/org/apache/doris/optimizer/OptConverterCtx.java b/fe/src/main/java/org/apache/doris/optimizer/OptConverterCtx.java new file mode 100644 index 00000000000000..700cca9a54d28a --- /dev/null +++ b/fe/src/main/java/org/apache/doris/optimizer/OptConverterCtx.java @@ -0,0 +1,71 @@ +// 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; + +import com.google.common.collect.Lists; +import com.google.common.collect.Maps; +import org.apache.doris.analysis.SlotDescriptor; +import org.apache.doris.analysis.SlotRef; +import org.apache.doris.analysis.TupleDescriptor; +import org.apache.doris.common.IdGenerator; +import org.apache.doris.optimizer.base.OptColumnRef; +import org.apache.doris.optimizer.base.OptColumnRefFactory; +import org.apache.doris.planner.PlanNodeId; + +import java.util.List; +import java.util.Map; + +// Used to record information when converting statement to optimization's expression +// and convert optimized expression back to plan node +public class OptConverterCtx { + private OptColumnRefFactory columnRefFactory = new OptColumnRefFactory(); + private Map slotIdToColumnRef = Maps.newHashMap(); + // map from OptColumnRef to SlotReference, + private Map columnIdToSlotRef = Maps.newHashMap(); + private IdGenerator planNodeIdGenerator = PlanNodeId.createGenerator(); + + // Convert a TupleDescriptor to a list of OptColumnRef and record map information + public List convertTuple(TupleDescriptor tupleDesc) { + List columnRefs = Lists.newArrayList(); + for (SlotDescriptor slotDesc : tupleDesc.getSlots()) { + columnRefs.add(createColumnRef(slotDesc)); + } + return columnRefs; + } + + // used to convert statement to OptExpression + public OptColumnRef getColumnRef(int slotId) { + return slotIdToColumnRef.get(slotId); + } + + // used to convert OptExpression to PlanNode + public SlotDescriptor getSlotRef(int columnId) { + return columnIdToSlotRef.get(columnId); + } + + public PlanNodeId nextPlanNodeId() { + return planNodeIdGenerator.getNextId(); + } + + private OptColumnRef createColumnRef(SlotDescriptor slotDesc) { + OptColumnRef columnRef = columnRefFactory.create(slotDesc.getLabel(), slotDesc.getType()); + slotIdToColumnRef.put(slotDesc.getId().asInt(), columnRef); + columnIdToSlotRef.put(columnRef.getId(), slotDesc); + return columnRef; + } +} diff --git a/fe/src/main/java/org/apache/doris/optimizer/StmtToExpressionConvertor.java b/fe/src/main/java/org/apache/doris/optimizer/StmtToExpressionConverter.java similarity index 95% rename from fe/src/main/java/org/apache/doris/optimizer/StmtToExpressionConvertor.java rename to fe/src/main/java/org/apache/doris/optimizer/StmtToExpressionConverter.java index df4f4840ecdaf2..804f7c67937c63 100644 --- a/fe/src/main/java/org/apache/doris/optimizer/StmtToExpressionConvertor.java +++ b/fe/src/main/java/org/apache/doris/optimizer/StmtToExpressionConverter.java @@ -53,9 +53,17 @@ import java.util.Map; // Used to convert QueryStmt to an OptExpression -public class StmtToExpressionConvertor { +public class StmtToExpressionConverter { private OptColumnRefFactory columnRefFactory = new OptColumnRefFactory(); private Map slotIdToColumnRef = Maps.newHashMap(); + // map from OptColumnRef to SlotReference + private Map columnIdToSlotRef = Maps.newHashMap(); + + private OptConverterCtx ctx; + + public StmtToExpressionConverter(OptConverterCtx ctx) { + this.ctx = ctx; + } public OptExpression convertQuery(QueryStmt stmt) { OptExpression root; @@ -152,7 +160,7 @@ public OptExpression convertTableRef(TableRef ref) { } public OptExpression convertBaseTableRef(BaseTableRef ref) { - List columnRefs = convertTuple(ref.getDesc()); + List columnRefs = ctx.convertTuple(ref.getDesc()); OptLogical op = null; switch (ref.getTable().getType()) { case OLAP: @@ -168,7 +176,7 @@ private OptExpression convertInlineView(InlineViewRef ref) { List resultExprs = ref.getViewStmt().getResultExprs(); - List columnRefs = convertTuple(ref.getDesc()); + List columnRefs = ctx.convertTuple(ref.getDesc()); List projElements = Lists.newArrayList(); for (int i = 0 ; i < columnRefs.size(); ++i) { @@ -180,17 +188,6 @@ private OptExpression convertInlineView(InlineViewRef ref) { return OptExpression.create(new OptLogicalProject(), childExpr, projList); } - private List convertTuple(TupleDescriptor desc) { - List refs = Lists.newArrayList(); - for (SlotDescriptor slot : desc.getSlots()) { - OptColumnRef ref = columnRefFactory.create(slot.getLabel(), slot.getType()); - - slotIdToColumnRef.put(slot.getId().asInt(), ref); - refs.add(ref); - } - return refs; - } - public OptExpression convertExpr(Expr expr) { if (expr instanceof BinaryPredicate) { return convertBinaryPredicate((BinaryPredicate) expr); @@ -236,7 +233,7 @@ private OptExpression convertArithmeticExpr(ArithmeticExpr expr) { } private OptExpression convertSlotRef(SlotRef ref) { - OptColumnRef columnRef = slotIdToColumnRef.get(ref.getSlotId().asInt()); + OptColumnRef columnRef = ctx.getColumnRef(ref.getSlotId().asInt()); Preconditions.checkArgument(columnRef != null, "Can not find ColumnRef through ref, ref=" + ref.debugString()); diff --git a/fe/src/main/java/org/apache/doris/optimizer/operator/OptItemArithmetic.java b/fe/src/main/java/org/apache/doris/optimizer/operator/OptItemArithmetic.java index 2e72896f4a40b2..1a2eaf07488444 100644 --- a/fe/src/main/java/org/apache/doris/optimizer/operator/OptItemArithmetic.java +++ b/fe/src/main/java/org/apache/doris/optimizer/operator/OptItemArithmetic.java @@ -21,6 +21,13 @@ import org.apache.doris.catalog.Type; import org.apache.doris.optimizer.OptUtils; +// In common case, the OptItemArithmetic has two children. Such as 'add', 'minus' +// OptItemArithmetic +// |--- OptItem(left child) +// |--- OptItem(right child) +// But for some cases, this has only one child, such as 'bitnot' +// OptItemArithmetic +// |--- OptItem(left child) public class OptItemArithmetic extends OptItem { private ArithmeticExpr.Operator op; @@ -29,6 +36,8 @@ public OptItemArithmetic(ArithmeticExpr.Operator op) { this.op = op; } + public ArithmeticExpr.Operator getOp() { return op; } + @Override public Type getReturnType() { return null; diff --git a/fe/src/main/java/org/apache/doris/optimizer/operator/OptItemBinaryPredicate.java b/fe/src/main/java/org/apache/doris/optimizer/operator/OptItemBinaryPredicate.java index 9c51ac45805bfd..09f5756763c6d3 100644 --- a/fe/src/main/java/org/apache/doris/optimizer/operator/OptItemBinaryPredicate.java +++ b/fe/src/main/java/org/apache/doris/optimizer/operator/OptItemBinaryPredicate.java @@ -21,6 +21,9 @@ import org.apache.doris.catalog.Type; import org.apache.doris.optimizer.OptUtils; +// OptItemBinaryPredicate +// |--- OptItem(left child) +// |--- OptItem(right child) public class OptItemBinaryPredicate extends OptItem { private BinaryPredicate.Operator op; diff --git a/fe/src/main/java/org/apache/doris/optimizer/operator/OptItemCase.java b/fe/src/main/java/org/apache/doris/optimizer/operator/OptItemCase.java index 05009acf5991da..2c8e433232f6b2 100644 --- a/fe/src/main/java/org/apache/doris/optimizer/operator/OptItemCase.java +++ b/fe/src/main/java/org/apache/doris/optimizer/operator/OptItemCase.java @@ -20,6 +20,14 @@ import org.apache.doris.catalog.Type; import org.apache.doris.optimizer.OptUtils; +// Indicates case expression 'CASE case_expr WHEN when_expr THEN then_expr ... ELSE else_expr' +// or 'CASE WHEN when_expr THEN then_expr ... ELSE else_expr' +// OptItemCase +// |--- case_expr +// |--- when_expr +// |--- then_expr +// ... +// |--- else_expr public class OptItemCase extends OptItem { private boolean hasCase; private boolean hasElse; @@ -32,6 +40,9 @@ public OptItemCase(boolean hasCase, boolean hasElse, Type type) { this.type = type; } + public boolean hasCase() { return hasCase; } + public boolean hasElse() { return hasElse; } + @Override public Type getReturnType() { return type; diff --git a/fe/src/main/java/org/apache/doris/optimizer/operator/OptItemCast.java b/fe/src/main/java/org/apache/doris/optimizer/operator/OptItemCast.java index e899e065775251..a3af82e9031000 100644 --- a/fe/src/main/java/org/apache/doris/optimizer/operator/OptItemCast.java +++ b/fe/src/main/java/org/apache/doris/optimizer/operator/OptItemCast.java @@ -20,6 +20,9 @@ import org.apache.doris.catalog.Type; import org.apache.doris.optimizer.OptUtils; +// indicates cast expression, such as 'cast(c1 as int)' +// OptItemCast +// |--- child public class OptItemCast extends OptItem { private Type destType; @@ -28,6 +31,8 @@ public OptItemCast(Type destType) { this.destType = destType; } + public Type getDestType() { return destType; } + @Override public Type getReturnType() { return destType; diff --git a/fe/src/main/java/org/apache/doris/optimizer/operator/OptItemInPredicate.java b/fe/src/main/java/org/apache/doris/optimizer/operator/OptItemInPredicate.java index fa491dba4a3d4b..00a43c5cdbf5fb 100644 --- a/fe/src/main/java/org/apache/doris/optimizer/operator/OptItemInPredicate.java +++ b/fe/src/main/java/org/apache/doris/optimizer/operator/OptItemInPredicate.java @@ -20,6 +20,13 @@ import org.apache.doris.catalog.Type; import org.apache.doris.optimizer.OptUtils; +// this predicate may have many children, +// OptItemInPredicate +// |--- child0 +// |--- child1 +// |--- child2 +// ... +// which indicates 'child0 in (child1, child1, ...)' public class OptItemInPredicate extends OptItem { boolean isNotIn; @@ -27,6 +34,7 @@ public OptItemInPredicate(boolean isNotIn) { super(OptOperatorType.OP_ITEM_IN_PREDICATE); this.isNotIn = isNotIn; } + public boolean isNotIn() { return isNotIn; } @Override public Type getReturnType() { diff --git a/fe/src/main/java/org/apache/doris/optimizer/operator/OptItemIsNullPredicate.java b/fe/src/main/java/org/apache/doris/optimizer/operator/OptItemIsNullPredicate.java index 4484577f78cadd..fcdd8c49f3c73d 100644 --- a/fe/src/main/java/org/apache/doris/optimizer/operator/OptItemIsNullPredicate.java +++ b/fe/src/main/java/org/apache/doris/optimizer/operator/OptItemIsNullPredicate.java @@ -20,6 +20,9 @@ import org.apache.doris.catalog.Type; import org.apache.doris.optimizer.OptUtils; +// indicates predicate 'c1 is null' or 'c1 is not null' +// OptItemIsNullPredicate +// |--- child public class OptItemIsNullPredicate extends OptItem { private boolean isNotNull; @@ -28,6 +31,8 @@ public OptItemIsNullPredicate(boolean isNotNull) { this.isNotNull = isNotNull; } + public boolean isNotNull() { return isNotNull; } + @Override public Type getReturnType() { return Type.BOOLEAN; diff --git a/fe/src/main/java/org/apache/doris/optimizer/operator/OptItemLikePredicate.java b/fe/src/main/java/org/apache/doris/optimizer/operator/OptItemLikePredicate.java index 790939127d8b06..a721a732096f82 100644 --- a/fe/src/main/java/org/apache/doris/optimizer/operator/OptItemLikePredicate.java +++ b/fe/src/main/java/org/apache/doris/optimizer/operator/OptItemLikePredicate.java @@ -21,6 +21,10 @@ import org.apache.doris.catalog.Type; import org.apache.doris.optimizer.OptUtils; +// This class is used to represent like predicate such as 'c1 like "abc%"' +// LikePredicate +// |--- OptItem(left child) +// |--- OptItem(right child) public class OptItemLikePredicate extends OptItem { private LikePredicate.Operator op; @@ -28,6 +32,7 @@ public OptItemLikePredicate(LikePredicate.Operator op) { super(OptOperatorType.OP_ITEM_LIKE_PREDICATE); this.op = op; } + public LikePredicate.Operator getOp() { return op; } @Override public Type getReturnType() { diff --git a/fe/src/main/java/org/apache/doris/optimizer/operator/OptLogicalMysqlScan.java b/fe/src/main/java/org/apache/doris/optimizer/operator/OptLogicalMysqlScan.java new file mode 100644 index 00000000000000..29a1629b0a57d7 --- /dev/null +++ b/fe/src/main/java/org/apache/doris/optimizer/operator/OptLogicalMysqlScan.java @@ -0,0 +1,54 @@ +// 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.operator; + +import org.apache.doris.catalog.MysqlTable; +import org.apache.doris.optimizer.base.OptColumnRef; +import org.apache.doris.optimizer.base.OptColumnRefSet; +import org.apache.doris.optimizer.base.RequiredLogicalProperty; +import org.apache.doris.optimizer.stat.Statistics; + +import java.util.List; + +public class OptLogicalMysqlScan extends OptLogical { + private MysqlTable table; + private List outputColumns; + + public OptLogicalMysqlScan(MysqlTable table, List columns) { + super(OptOperatorType.OP_LOGICAL_MYSQL_SCAN); + this.table = table; + this.outputColumns = columns; + } + + public MysqlTable getTable() { return table; } + + @Override + public Statistics deriveStat(OptExpressionHandle exprHandle, RequiredLogicalProperty property) { + return null; + } + + @Override + public OptColumnRefSet requiredStatForChild(OptExpressionHandle exprHandle, RequiredLogicalProperty property, int childIndex) { + return null; + } + + @Override + public OptColumnRefSet getOutputColumns(OptExpressionHandle exprHandle) { + return new OptColumnRefSet(outputColumns); + } +} 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 8126d4b632455e..157e6f46f445dd 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 @@ -33,7 +33,6 @@ import java.util.List; public class OptLogicalScan extends OptLogical { - private List outputs; private OlapTable table; diff --git a/fe/src/main/java/org/apache/doris/optimizer/operator/OptOperatorType.java b/fe/src/main/java/org/apache/doris/optimizer/operator/OptOperatorType.java index 6561917059bf0d..37a7906f6aa202 100644 --- a/fe/src/main/java/org/apache/doris/optimizer/operator/OptOperatorType.java +++ b/fe/src/main/java/org/apache/doris/optimizer/operator/OptOperatorType.java @@ -28,6 +28,7 @@ public enum OptOperatorType { OP_LOGICAL_FULL_OUTER_JOIN("LogicalFullOuterJoin"), OP_LOGICAL_PROJECT("LogicalProject"), OP_LOGICAL_SCAN("LogicalScan"), + OP_LOGICAL_MYSQL_SCAN("LogicalMysqlScan"), OP_LOGICAL_SELECT("LogicalSelect"), OP_LOGICAL_UNION("LogicalUnion"), OP_LOGICAL_LIMIT("LogicalLimit"), @@ -38,6 +39,7 @@ public enum OptOperatorType { OP_PHYSICAL_SORT("PhysicalSort"), OP_PHYSICAL_UNION("PhysicalUnion"), OP_PHYSICAL_DISTRIBUTION("PhysicalDistribution"), + OP_PHYSICAL_MYSQL_SCAN("PhysicalMysqlScan"), OP_ITEM_AGG_FUNC("ItemAggregateFunction"), OP_ITEM_ARITHMETIC("ItemArithmetic"), diff --git a/fe/src/main/java/org/apache/doris/optimizer/operator/OptPhysicalMysqlScan.java b/fe/src/main/java/org/apache/doris/optimizer/operator/OptPhysicalMysqlScan.java new file mode 100644 index 00000000000000..29615d0e79f6f1 --- /dev/null +++ b/fe/src/main/java/org/apache/doris/optimizer/operator/OptPhysicalMysqlScan.java @@ -0,0 +1,45 @@ +// 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.operator; + +import org.apache.doris.optimizer.base.DistributionEnforcerProperty; +import org.apache.doris.optimizer.base.OptColumnRefSet; +import org.apache.doris.optimizer.base.OrderEnforcerProperty; +import org.apache.doris.optimizer.base.RequiredPhysicalProperty; + +public class OptPhysicalMysqlScan extends OptPhysical { + + public OptPhysicalMysqlScan() { + super(OptOperatorType.OP_PHYSICAL_MYSQL_SCAN); + } + + @Override + public OrderEnforcerProperty getChildReqdOrder(OptExpressionHandle handle, OrderEnforcerProperty reqdOrder, int childIndex) { + return null; + } + + @Override + public DistributionEnforcerProperty getChildReqdDistribution(OptExpressionHandle handle, DistributionEnforcerProperty reqdDistribution, int childIndex) { + return null; + } + + @Override + protected OptColumnRefSet deriveChildReqdColumns(OptExpressionHandle exprHandle, RequiredPhysicalProperty property, int childIndex) { + return null; + } +} diff --git a/fe/src/main/java/org/apache/doris/optimizer/rule/implementation/AggToHashAggRule.java b/fe/src/main/java/org/apache/doris/optimizer/rule/implementation/AggToHashAggRule.java index 3a1c15934341bb..2a91b9e57e6766 100644 --- a/fe/src/main/java/org/apache/doris/optimizer/rule/implementation/AggToHashAggRule.java +++ b/fe/src/main/java/org/apache/doris/optimizer/rule/implementation/AggToHashAggRule.java @@ -17,16 +17,7 @@ package org.apache.doris.optimizer.rule.implementation; -import com.google.common.base.Preconditions; -import com.google.common.collect.Lists; -import org.apache.doris.analysis.AggregateInfo; -import org.apache.doris.analysis.Expr; -import org.apache.doris.analysis.FunctionCallExpr; import org.apache.doris.optimizer.OptExpression; -import org.apache.doris.optimizer.StmtToExpressionConvertor; -import org.apache.doris.optimizer.base.ItemUtils; -import org.apache.doris.optimizer.base.OptColumnRefSet; -import org.apache.doris.optimizer.base.OptPhysicalProperty; import org.apache.doris.optimizer.operator.*; import org.apache.doris.optimizer.rule.OptRuleType; @@ -69,7 +60,7 @@ public void transform(OptExpression expr, List newExprs) { // final AggregateInfo mergeInfo = operator.getAggInfo().getMergeAggInfo(); // final List mergeInputs = Lists.newArrayList(); // mergeInputs.add(aggregateExpr); -// final StmtToExpressionConvertor convertor = new StmtToExpressionConvertor(); +// final StmtToExpressionConverter convertor = new StmtToExpressionConverter(); // for (FunctionCallExpr func : mergeInfo.getAggregateExprs()) { // mergeInputs.add(convertor.convertExpr(func)); // }