You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@doris.apache.org by mo...@apache.org on 2022/06/22 03:54:34 UTC
[doris] branch master updated: [feature](nereids) Add ssb related expressions and PlanNode (#10227)
This is an automated email from the ASF dual-hosted git repository.
morningman pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/doris.git
The following commit(s) were added to refs/heads/master by this push:
new 531c9abac8 [feature](nereids) Add ssb related expressions and PlanNode (#10227)
531c9abac8 is described below
commit 531c9abac8556e061961bf2f5a686b53025395e5
Author: zhengshiJ <32...@users.noreply.github.com>
AuthorDate: Wed Jun 22 11:54:28 2022 +0800
[feature](nereids) Add ssb related expressions and PlanNode (#10227)
Add related expressions and AggPlan and SortPlan.
This PR includes the addition of the following expression types:
Arithmetic/BetweenPredicate/CompoundPredicate/FunctionCall.
PlanNode:
LogicalAggregation/LogicalSort
Add a ut to verify related expressions and node parsing
---
.../antlr4/org/apache/doris/nereids/DorisLexer.g4 | 3 +-
.../antlr4/org/apache/doris/nereids/DorisParser.g4 | 65 ++++++-
.../java/org/apache/doris/catalog/FunctionSet.java | 1 -
.../doris/nereids/operators/OperatorType.java | 2 +
.../plans/logical/LogicalAggregation.java | 98 ++++++++++
.../operators/plans/logical/LogicalSort.java | 114 +++++++++++
.../doris/nereids/parser/LogicalPlanBuilder.java | 213 ++++++++++++++++++++-
.../org/apache/doris/nereids/trees/NodeType.java | 15 ++
.../nereids/trees/analysis/FunctionParams.java | 83 ++++++++
.../trees/{NodeType.java => expressions/Add.java} | 41 ++--
.../trees/{NodeType.java => expressions/And.java} | 45 ++---
.../nereids/trees/expressions/Arithmetic.java | 134 +++++++++++++
.../trees/expressions/BetweenPredicate.java | 77 ++++++++
.../trees/expressions/ComparisonPredicate.java | 3 +-
.../{FunctionCall.java => CompoundPredicate.java} | 49 ++---
.../{NodeType.java => expressions/Divide.java} | 41 ++--
.../nereids/trees/expressions/Expression.java | 1 +
.../trees/expressions/ExpressionVisitor.java | 13 ++
.../nereids/trees/expressions/FunctionCall.java | 40 ++--
.../doris/nereids/trees/expressions/Literal.java | 3 +-
.../trees/{NodeType.java => expressions/Mod.java} | 41 ++--
.../{NodeType.java => expressions/Multiply.java} | 40 ++--
.../trees/{NodeType.java => expressions/Or.java} | 45 ++---
.../{NodeType.java => expressions/Subtract.java} | 41 ++--
.../trees/expressions/ExpressionParserTest.java | 137 +++++++++++++
25 files changed, 1060 insertions(+), 285 deletions(-)
diff --git a/fe/fe-core/src/main/antlr4/org/apache/doris/nereids/DorisLexer.g4 b/fe/fe-core/src/main/antlr4/org/apache/doris/nereids/DorisLexer.g4
index c07854e0cc..0958acaabf 100644
--- a/fe/fe-core/src/main/antlr4/org/apache/doris/nereids/DorisLexer.g4
+++ b/fe/fe-core/src/main/antlr4/org/apache/doris/nereids/DorisLexer.g4
@@ -103,6 +103,7 @@ AS: 'AS';
ASC: 'ASC';
AT: 'AT';
AUTHORIZATION: 'AUTHORIZATION';
+AVG: 'AVG';
BETWEEN: 'BETWEEN';
BOTH: 'BOTH';
BUCKET: 'BUCKET';
@@ -159,7 +160,6 @@ DIRECTORIES: 'DIRECTORIES';
DIRECTORY: 'DIRECTORY';
DISTINCT: 'DISTINCT';
DISTRIBUTE: 'DISTRIBUTE';
-DIV: 'DIV';
DROP: 'DROP';
ELSE: 'ELSE';
END: 'END';
@@ -316,6 +316,7 @@ STRATIFY: 'STRATIFY';
STRUCT: 'STRUCT';
SUBSTR: 'SUBSTR';
SUBSTRING: 'SUBSTRING';
+SUM: 'SUM';
SYNC: 'SYNC';
SYSTEM_TIME: 'SYSTEM_TIME';
SYSTEM_VERSION: 'SYSTEM_VERSION';
diff --git a/fe/fe-core/src/main/antlr4/org/apache/doris/nereids/DorisParser.g4 b/fe/fe-core/src/main/antlr4/org/apache/doris/nereids/DorisParser.g4
index edf28c1d7e..b175d9748d 100644
--- a/fe/fe-core/src/main/antlr4/org/apache/doris/nereids/DorisParser.g4
+++ b/fe/fe-core/src/main/antlr4/org/apache/doris/nereids/DorisParser.g4
@@ -52,8 +52,9 @@ statement
: query #statementDefault
;
+// -----------------Query-----------------
query
- : queryTerm
+ : queryTerm queryOrganization
;
queryTerm
@@ -68,7 +69,9 @@ queryPrimary
querySpecification
: selectClause
fromClause?
- whereClause? #regularQuerySpecification
+ whereClause?
+ aggClause?
+ havingClause? #regularQuerySpecification
;
selectClause
@@ -91,6 +94,30 @@ joinRelation
: (joinType) JOIN right=relationPrimary joinCriteria?
;
+aggClause
+ : GROUP BY groupByItem?
+ ;
+
+groupByItem
+ : expression (',' expression)*
+ ;
+
+havingClause
+ : HAVING booleanExpression
+ ;
+
+queryOrganization
+ : sortClause
+ ;
+
+sortClause
+ : (ORDER BY sortItem (',' sortItem)*)?
+ ;
+
+sortItem
+ : expression ordering = (ASC | DESC)?
+ ;
+
joinType
: INNER?
| CROSS
@@ -128,6 +155,8 @@ multipartIdentifier
: parts+=errorCapturingIdentifier (DOT parts+=errorCapturingIdentifier)*
;
+
+// -----------------Expression-----------------
namedExpression
: expression (AS? name=errorCapturingIdentifier)?
;
@@ -141,12 +170,21 @@ expression
;
booleanExpression
- : NOT booleanExpression #not
- | valueExpression #predicated
+ : NOT booleanExpression #logicalNot
+ | valueExpression predicate? #predicated
+ | left=booleanExpression operator=AND right=booleanExpression #logicalBinary
+ | left=booleanExpression operator=OR right=booleanExpression #logicalBinary
+ ;
+
+predicate
+ : NOT? kind=BETWEEN lower=valueExpression AND upper=valueExpression
;
valueExpression
: primaryExpression #valueExpressionDefault
+ | operator=(MINUS | PLUS) valueExpression #arithmeticUnary
+ | left=valueExpression operator=(ASTERISK | SLASH | PERCENT) right=valueExpression #arithmeticBinary
+ | left=valueExpression operator=(PLUS | MINUS) right=valueExpression #arithmeticBinary
| left=valueExpression comparisonOperator right=valueExpression #comparison
;
@@ -154,6 +192,7 @@ primaryExpression
: constant #constantDefault
| ASTERISK #star
| qualifiedName DOT ASTERISK #star
+ | functionExpression #functioncall
| LEFT_PAREN query RIGHT_PAREN #subqueryExpression
| identifier #columnReference
| base=primaryExpression DOT fieldName=identifier #dereference
@@ -170,6 +209,10 @@ constant
| STRING+ #stringLiteral
;
+functionExpression
+ : aggFunction #aggFunctions
+ ;
+
comparisonOperator
: EQ | NEQ | LT | LTE | GT | GTE | NSEQ
;
@@ -178,6 +221,14 @@ booleanValue
: TRUE | FALSE
;
+//TODO: In the future, instead of specifying the function name,
+// the function information is obtained by parsing the catalog. This method is more scalable.
+aggFunction
+ : AVG '(' DISTINCT? expression ')'
+ | SUM '(' DISTINCT? expression ')'
+ ;
+
+
// this rule is used for explicitly capturing wrong identifiers such as test-table, which should actually be `test-table`
// replace identifier with errorCapturingIdentifier where the immediate follow symbol is not an expression, otherwise
// valid expressions such as "a-b" can be recognized as an identifier
@@ -234,6 +285,7 @@ ansiNonReserved
| ARRAY
| ASC
| AT
+ | AVG
| BETWEEN
| BUCKET
| BUCKETS
@@ -276,7 +328,6 @@ ansiNonReserved
| DIRECTORIES
| DIRECTORY
| DISTRIBUTE
- | DIV
| DROP
| ESCAPED
| EXCHANGE
@@ -394,6 +445,7 @@ ansiNonReserved
| STRUCT
| SUBSTR
| SUBSTRING
+ | SUM
| SYNC
| SYSTEM_TIME
| SYSTEM_VERSION
@@ -474,6 +526,7 @@ nonReserved
| ASC
| AT
| AUTHORIZATION
+ | AVG
| BETWEEN
| BOTH
| BUCKET
@@ -529,7 +582,6 @@ nonReserved
| DIRECTORY
| DISTINCT
| DISTRIBUTE
- | DIV
| DROP
| ELSE
| END
@@ -674,6 +726,7 @@ nonReserved
| STRUCT
| SUBSTR
| SUBSTRING
+ | SUM
| SYNC
| SYSTEM_TIME
| SYSTEM_VERSION
diff --git a/fe/fe-core/src/main/java/org/apache/doris/catalog/FunctionSet.java b/fe/fe-core/src/main/java/org/apache/doris/catalog/FunctionSet.java
index 9f8e978fe2..884a8fa452 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/catalog/FunctionSet.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/catalog/FunctionSet.java
@@ -1937,7 +1937,6 @@ public class FunctionSet<T> {
}
}
-
// Sum
String []sumNames = {"sum", "sum_distinct"};
for (String name : sumNames) {
diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/operators/OperatorType.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/operators/OperatorType.java
index 3a7554aad6..ad112935cf 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/nereids/operators/OperatorType.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/operators/OperatorType.java
@@ -36,6 +36,8 @@ public enum OperatorType {
LOGICAL_PROJECT,
LOGICAL_FILTER,
LOGICAL_JOIN,
+ LOGICAL_AGGREGATION,
+ LOGICAL_SORT,
GROUP_PLAN,
// physical plan
diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/operators/plans/logical/LogicalAggregation.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/operators/plans/logical/LogicalAggregation.java
new file mode 100644
index 0000000000..eb6172420a
--- /dev/null
+++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/operators/plans/logical/LogicalAggregation.java
@@ -0,0 +1,98 @@
+// 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.operators.plans.logical;
+
+import org.apache.doris.nereids.exceptions.UnboundException;
+import org.apache.doris.nereids.operators.OperatorType;
+import org.apache.doris.nereids.trees.expressions.Expression;
+import org.apache.doris.nereids.trees.expressions.NamedExpression;
+import org.apache.doris.nereids.trees.expressions.Slot;
+import org.apache.doris.nereids.trees.plans.Plan;
+
+import com.google.common.collect.ImmutableList;
+import org.apache.commons.lang3.StringUtils;
+
+import java.util.List;
+
+/**
+ * Logical Aggregation plan operator.
+ *
+ *eg:select a, sum(b), c from table group by a, c;
+ * groupByExpressions: Column field after group by. eg: a, c;
+ * outputExpressions: Column field after select. eg: a, sum(b), c;
+ *
+ * Each agg node only contains the select statement field of the same layer,
+ * and other agg nodes in the subquery contain.
+ */
+public class LogicalAggregation extends LogicalUnaryOperator {
+
+ private final List<Expression> groupByExpressions;
+ private final List<? extends NamedExpression> outputExpressions;
+
+ /**
+ * Desc: Constructor for LogicalAggregation.
+ */
+ public LogicalAggregation(List<Expression> groupByExpressions,
+ List<? extends NamedExpression> outputExpressions) {
+ super(OperatorType.LOGICAL_AGGREGATION);
+ this.groupByExpressions = groupByExpressions;
+ this.outputExpressions = outputExpressions;
+ }
+
+ /**
+ * Get GroupByAggregation list.
+ *
+ * @return all group by of this node.
+ */
+ public List<Expression> getGroupByExpressions() {
+ return groupByExpressions;
+ }
+
+ /**
+ * Get outputExpressions list.
+ *
+ * @return all agg expressions.
+ */
+ public List<? extends NamedExpression> getoutputExpressions() {
+ return outputExpressions;
+ }
+
+ @Override
+ public String toString() {
+ return "Aggregation (" + "outputExpressions: " + StringUtils.join(outputExpressions, ", ")
+ + ", groupByExpressions: " + StringUtils.join(groupByExpressions, ", ") + ")";
+ }
+
+ @Override
+ public List<Slot> computeOutput(Plan input) {
+ return outputExpressions.stream()
+ .map(namedExpr -> {
+ try {
+ return namedExpr.toSlot();
+ } catch (UnboundException e) {
+ throw new IllegalStateException(e);
+ }
+ })
+ .collect(ImmutableList.toImmutableList());
+ }
+
+ @Override
+ public List<Expression> getExpressions() {
+ return new ImmutableList.Builder<Expression>().addAll(groupByExpressions).addAll(outputExpressions).build();
+ }
+}
diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/operators/plans/logical/LogicalSort.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/operators/plans/logical/LogicalSort.java
new file mode 100644
index 0000000000..b1984051f7
--- /dev/null
+++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/operators/plans/logical/LogicalSort.java
@@ -0,0 +1,114 @@
+// 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.operators.plans.logical;
+
+import org.apache.doris.nereids.operators.OperatorType;
+import org.apache.doris.nereids.trees.expressions.Expression;
+import org.apache.doris.nereids.trees.expressions.Slot;
+import org.apache.doris.nereids.trees.plans.Plan;
+
+import com.google.common.collect.ImmutableList;
+import org.apache.commons.lang3.StringUtils;
+
+import java.util.List;
+import java.util.Objects;
+import java.util.stream.Collectors;
+
+/**
+ * Logical Sort plan operator.
+ *
+ * eg: select * from table order by a, b desc;
+ * sortItems: list of column information after order by. eg:[a, asc],[b, desc].
+ * SortItems: Contains order expression information and sorting method. Default is ascending.
+ */
+public class LogicalSort extends LogicalUnaryOperator {
+
+ private List<SortItems> sortItems;
+
+ /**
+ * Constructor for SortItems.
+ */
+ public LogicalSort(List<SortItems> sortItems) {
+ super(OperatorType.LOGICAL_SORT);
+ this.sortItems = Objects.requireNonNull(sortItems, "sorItems can not be null");
+ }
+
+ @Override
+ public String toString() {
+ return "Sort (" + StringUtils.join(sortItems, ", ") + ")";
+ }
+
+ @Override
+ public List<Slot> computeOutput(Plan input) {
+ return input.getOutput();
+ }
+
+ /**
+ * Get SortItems.
+ *
+ * @return List of SortItems.
+ */
+ public List<SortItems> getSortItems() {
+ return sortItems;
+ }
+
+ @Override
+ public List<Expression> getExpressions() {
+ return new ImmutableList.Builder<Expression>().addAll(
+ sortItems.stream().map(expr -> expr.getSort()).collect(Collectors.toList()))
+ .build();
+ }
+
+ /**
+ * SortItem. Show sort expressions and their order types.
+ */
+ public static class SortItems {
+ /**
+ * enum of OrderDirection.
+ */
+ public enum OrderDirection {
+ ASC,
+ DESC
+ }
+
+ private final Expression sort;
+ private final OrderDirection orderDirection;
+
+ public SortItems(Expression sort, OrderDirection orderDirection) {
+ this.sort = sort;
+ this.orderDirection = orderDirection;
+ }
+
+ public Expression getSort() {
+ return sort;
+ }
+
+ /**
+ * Get OrderDirection.
+ *
+ * @return boolean.
+ */
+ public OrderDirection getOrderDirection() {
+ return orderDirection;
+ }
+
+ public String toString() {
+ return "Expression: " + sort.sql() + " OrderDirection: " + orderDirection.toString();
+ }
+ }
+}
diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/parser/LogicalPlanBuilder.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/parser/LogicalPlanBuilder.java
index c90524f3ce..23b697ede3 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/nereids/parser/LogicalPlanBuilder.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/parser/LogicalPlanBuilder.java
@@ -19,29 +19,38 @@ package org.apache.doris.nereids.parser;
import org.apache.doris.nereids.DorisParser;
+import org.apache.doris.nereids.DorisParser.AggClauseContext;
+import org.apache.doris.nereids.DorisParser.AggFunctionsContext;
+import org.apache.doris.nereids.DorisParser.ArithmeticBinaryContext;
+import org.apache.doris.nereids.DorisParser.ArithmeticUnaryContext;
import org.apache.doris.nereids.DorisParser.BooleanLiteralContext;
import org.apache.doris.nereids.DorisParser.ColumnReferenceContext;
import org.apache.doris.nereids.DorisParser.ComparisonContext;
import org.apache.doris.nereids.DorisParser.DereferenceContext;
import org.apache.doris.nereids.DorisParser.ExpressionContext;
import org.apache.doris.nereids.DorisParser.FromClauseContext;
+import org.apache.doris.nereids.DorisParser.GroupByItemContext;
import org.apache.doris.nereids.DorisParser.IdentifierListContext;
import org.apache.doris.nereids.DorisParser.IdentifierSeqContext;
import org.apache.doris.nereids.DorisParser.IntegerLiteralContext;
import org.apache.doris.nereids.DorisParser.JoinCriteriaContext;
import org.apache.doris.nereids.DorisParser.JoinRelationContext;
+import org.apache.doris.nereids.DorisParser.LogicalBinaryContext;
+import org.apache.doris.nereids.DorisParser.LogicalNotContext;
import org.apache.doris.nereids.DorisParser.MultipartIdentifierContext;
import org.apache.doris.nereids.DorisParser.NamedExpressionContext;
import org.apache.doris.nereids.DorisParser.NamedExpressionSeqContext;
-import org.apache.doris.nereids.DorisParser.NotContext;
import org.apache.doris.nereids.DorisParser.NullLiteralContext;
+import org.apache.doris.nereids.DorisParser.PredicateContext;
import org.apache.doris.nereids.DorisParser.PredicatedContext;
import org.apache.doris.nereids.DorisParser.QualifiedNameContext;
import org.apache.doris.nereids.DorisParser.QueryContext;
+import org.apache.doris.nereids.DorisParser.QueryOrganizationContext;
import org.apache.doris.nereids.DorisParser.RegularQuerySpecificationContext;
import org.apache.doris.nereids.DorisParser.RelationContext;
import org.apache.doris.nereids.DorisParser.SelectClauseContext;
import org.apache.doris.nereids.DorisParser.SingleStatementContext;
+import org.apache.doris.nereids.DorisParser.SortItemContext;
import org.apache.doris.nereids.DorisParser.StarContext;
import org.apache.doris.nereids.DorisParser.StringLiteralContext;
import org.apache.doris.nereids.DorisParser.TableNameContext;
@@ -52,20 +61,35 @@ import org.apache.doris.nereids.analyzer.UnboundRelation;
import org.apache.doris.nereids.analyzer.UnboundSlot;
import org.apache.doris.nereids.analyzer.UnboundStar;
import org.apache.doris.nereids.operators.plans.JoinType;
+import org.apache.doris.nereids.operators.plans.logical.LogicalAggregation;
import org.apache.doris.nereids.operators.plans.logical.LogicalFilter;
import org.apache.doris.nereids.operators.plans.logical.LogicalJoin;
import org.apache.doris.nereids.operators.plans.logical.LogicalProject;
+import org.apache.doris.nereids.operators.plans.logical.LogicalSort;
+import org.apache.doris.nereids.operators.plans.logical.LogicalSort.SortItems;
+import org.apache.doris.nereids.operators.plans.logical.LogicalSort.SortItems.OrderDirection;
+import org.apache.doris.nereids.trees.analysis.FunctionParams;
+import org.apache.doris.nereids.trees.expressions.Add;
import org.apache.doris.nereids.trees.expressions.Alias;
+import org.apache.doris.nereids.trees.expressions.And;
+import org.apache.doris.nereids.trees.expressions.Arithmetic;
+import org.apache.doris.nereids.trees.expressions.BetweenPredicate;
+import org.apache.doris.nereids.trees.expressions.Divide;
import org.apache.doris.nereids.trees.expressions.EqualTo;
import org.apache.doris.nereids.trees.expressions.Expression;
+import org.apache.doris.nereids.trees.expressions.FunctionCall;
import org.apache.doris.nereids.trees.expressions.GreaterThan;
import org.apache.doris.nereids.trees.expressions.GreaterThanEqual;
import org.apache.doris.nereids.trees.expressions.LessThan;
import org.apache.doris.nereids.trees.expressions.LessThanEqual;
import org.apache.doris.nereids.trees.expressions.Literal;
+import org.apache.doris.nereids.trees.expressions.Mod;
+import org.apache.doris.nereids.trees.expressions.Multiply;
import org.apache.doris.nereids.trees.expressions.NamedExpression;
import org.apache.doris.nereids.trees.expressions.Not;
import org.apache.doris.nereids.trees.expressions.NullSafeEqual;
+import org.apache.doris.nereids.trees.expressions.Or;
+import org.apache.doris.nereids.trees.expressions.Subtract;
import org.apache.doris.nereids.trees.plans.logical.LogicalBinaryPlan;
import org.apache.doris.nereids.trees.plans.logical.LogicalLeafPlan;
import org.apache.doris.nereids.trees.plans.logical.LogicalPlan;
@@ -74,11 +98,13 @@ import org.apache.doris.nereids.trees.plans.logical.LogicalUnaryPlan;
import com.google.common.collect.Lists;
import org.antlr.v4.runtime.ParserRuleContext;
import org.antlr.v4.runtime.RuleContext;
+import org.antlr.v4.runtime.Token;
import org.antlr.v4.runtime.tree.ParseTree;
import org.antlr.v4.runtime.tree.RuleNode;
import org.antlr.v4.runtime.tree.TerminalNode;
import org.apache.commons.collections.CollectionUtils;
+import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.function.BiFunction;
@@ -132,11 +158,18 @@ public class LogicalPlanBuilder extends DorisParserBaseVisitor<Object> {
public LogicalPlan visitQuery(QueryContext ctx) {
Supplier<LogicalPlan> f = () -> {
// TODO: need to add withQueryResultClauses and withCTE
- return plan(ctx.queryTerm());
+ LogicalPlan query = plan(ctx.queryTerm());
+ LogicalPlan queryOrganization = withQueryOrganization(ctx.queryOrganization(), query);
+ return queryOrganization;
};
return ParserUtils.withOrigin(ctx, f);
}
+ private LogicalPlan withQueryOrganization(QueryOrganizationContext ctx, LogicalPlan children) {
+ List<SortItems> sortItems = visitQueryOrganization(ctx);
+ return sortItems == null ? children : new LogicalUnaryPlan(new LogicalSort(sortItems), children);
+ }
+
@Override
public LogicalPlan visitRegularQuerySpecification(RegularQuerySpecificationContext ctx) {
Supplier<LogicalPlan> f = () -> {
@@ -146,7 +179,8 @@ public class LogicalPlanBuilder extends DorisParserBaseVisitor<Object> {
ctx,
ctx.selectClause(),
ctx.whereClause(),
- from);
+ from,
+ ctx.aggClause());
};
return ParserUtils.withOrigin(ctx, f);
}
@@ -162,8 +196,8 @@ public class LogicalPlanBuilder extends DorisParserBaseVisitor<Object> {
List<Expression> expressions = Lists.newArrayList();
if (ctx != null) {
for (NamedExpressionContext namedExpressionContext : ctx.namedExpression()) {
- NamedExpression namedExpression = typedVisit(namedExpressionContext);
- expressions.add(namedExpression);
+ Expression expression = typedVisit(namedExpressionContext);
+ expressions.add(expression);
}
}
return expressions;
@@ -180,13 +214,15 @@ public class LogicalPlanBuilder extends DorisParserBaseVisitor<Object> {
ParserRuleContext ctx,
SelectClauseContext selectClause,
WhereClauseContext whereClause,
- LogicalPlan relation) {
+ LogicalPlan relation,
+ AggClauseContext aggClause) {
Supplier<LogicalPlan> f = () -> {
// Filter(expression(ctx.booleanExpression), plan);
LogicalPlan plan = visitCommonSelectQueryClausePlan(
relation,
visitNamedExpressionSeq(selectClause.namedExpressionSeq()),
- whereClause);
+ whereClause,
+ aggClause);
// TODO: process hint
return plan;
};
@@ -196,7 +232,8 @@ public class LogicalPlanBuilder extends DorisParserBaseVisitor<Object> {
private LogicalPlan visitCommonSelectQueryClausePlan(
LogicalPlan relation,
List<Expression> expressions,
- WhereClauseContext whereClause) {
+ WhereClauseContext whereClause,
+ AggClauseContext aggClause) {
// TODO: add lateral views
// val withLateralView = lateralView.asScala.foldLeft(relation)(withGenerate)
@@ -218,7 +255,14 @@ public class LogicalPlanBuilder extends DorisParserBaseVisitor<Object> {
withProject = withFilter;
}
- return withProject;
+ LogicalPlan withAgg;
+ if (aggClause != null) {
+ withAgg = withAggClause(namedExpressions, aggClause.groupByItem(), withFilter);
+ } else {
+ withAgg = withProject;
+ }
+
+ return withAgg;
}
@Override
@@ -278,6 +322,50 @@ public class LogicalPlanBuilder extends DorisParserBaseVisitor<Object> {
return last;
}
+ private LogicalPlan withAggClause(List<NamedExpression> aggExpressions,
+ GroupByItemContext ctx, LogicalPlan aggClause) {
+ List<Expression> tmpExpressions = new ArrayList<>();
+ for (ExpressionContext expressionCtx : ctx.expression()) {
+ tmpExpressions.add(typedVisit(expressionCtx));
+ }
+ return new LogicalUnaryPlan(new LogicalAggregation(tmpExpressions, aggExpressions), aggClause);
+ }
+
+ /**
+ * Generate sortItems.
+ *
+ * @param ctx SortItemContext
+ * @return SortItems
+ */
+ public SortItems genSortItems(SortItemContext ctx) {
+ OrderDirection orderDirection;
+ if (ctx.DESC() != null) {
+ orderDirection = OrderDirection.DESC;
+ } else {
+ orderDirection = OrderDirection.ASC;
+ }
+ Expression expression = typedVisit(ctx.expression());
+ return new SortItems(expression, orderDirection);
+ }
+
+ /**
+ * Create SortItems list.
+ *
+ * @param ctx QueryOrganizationContext
+ * @return List of SortItems
+ */
+ public List<SortItems> visitQueryOrganization(QueryOrganizationContext ctx) {
+ List<SortItems> sortItems = new ArrayList<>();
+ if (ctx.sortClause().ORDER() != null) {
+ for (SortItemContext sortItemContext : ctx.sortClause().sortItem()) {
+ sortItems.add(genSortItems(sortItemContext));
+ }
+ return new ArrayList<>(sortItems);
+ } else {
+ return null;
+ }
+ }
+
/**
* Create an aliased table reference. This is typically used in FROM clauses.
*/
@@ -404,11 +492,26 @@ public class LogicalPlanBuilder extends DorisParserBaseVisitor<Object> {
* not 1=1
*/
@Override
- public Expression visitNot(NotContext ctx) {
+ public Expression visitLogicalNot(LogicalNotContext ctx) {
Expression child = expression(ctx.booleanExpression());
return new Not(child);
}
+ @Override
+ public Expression visitLogicalBinary(LogicalBinaryContext ctx) {
+ Expression left = expression(ctx.left);
+ Expression right = expression(ctx.right);
+
+ switch (ctx.operator.getType()) {
+ case DorisParser.AND:
+ return new And(left, right);
+ case DorisParser.OR:
+ return new Or(left, right);
+ default:
+ return null;
+ }
+ }
+
/**
* Create a predicated expression. A predicated expression is a normal expression with a
* predicate attached to it, for example:
@@ -420,9 +523,99 @@ public class LogicalPlanBuilder extends DorisParserBaseVisitor<Object> {
public Expression visitPredicated(PredicatedContext ctx) {
Expression e = expression(ctx.valueExpression());
// TODO: add predicate(is not null ...)
+ if (ctx.predicate() != null) {
+ return withPredicate(ctx.predicate(), e);
+ }
return e;
}
+ /**
+ * match predicate type and generate different predicates.
+ *
+ * @param ctx PredicateContext
+ * @param e Expression
+ * @return Expression
+ */
+ public Expression withPredicate(PredicateContext ctx, Expression e) {
+ switch (ctx.kind.getType()) {
+ case DorisParser.BETWEEN:
+ return withBetween(ctx, e);
+ default:
+ return null;
+ }
+ }
+
+ /**
+ * Generate between predicate.
+ *
+ * @param ctx PredicateContext
+ * @param e Expression
+ * @return Expression
+ */
+ public Expression withBetween(PredicateContext ctx, Expression e) {
+ boolean isNotBetween = ctx.NOT() != null ? true : false;
+ BetweenPredicate betweenPredicate = new BetweenPredicate(
+ e,
+ expression(ctx.lower),
+ expression(ctx.upper)
+ );
+ return isNotBetween ? new Not(betweenPredicate) : betweenPredicate;
+ }
+
+ @Override
+ public Expression visitArithmeticUnary(ArithmeticUnaryContext ctx) {
+ Expression e = expression(ctx);
+ switch (ctx.operator.getType()) {
+ case DorisParser.PLUS:
+ return e;
+ case DorisParser.MINUS:
+ //TODO: Add single operator subtraction
+ default:
+ return null;
+ }
+ }
+
+ @Override
+ public Expression visitArithmeticBinary(ArithmeticBinaryContext ctx) {
+ Expression left = expression(ctx.left);
+ Expression right = expression(ctx.right);
+
+ return genArithmetic(ctx.operator, left, right);
+ }
+
+ private Arithmetic genArithmetic(Token token, Expression left, Expression right) {
+ switch (token.getType()) {
+ case DorisParser.ASTERISK:
+ return new Multiply(left, right);
+ case DorisParser.SLASH:
+ return new Divide(left, right);
+ case DorisParser.PERCENT:
+ return new Mod(left, right);
+ case DorisParser.PLUS:
+ return new Add(left, right);
+ case DorisParser.MINUS:
+ return new Subtract(left, right);
+ default:
+ return null;
+ }
+ }
+
+ @Override
+ public Expression visitAggFunctions(AggFunctionsContext ctx) {
+ // TODO:In the future, instead of specifying the function name,
+ // the function information is obtained by parsing the catalog. This method is more scalable.
+ String functionName = "";
+ if (ctx.aggFunction().SUM() != null) {
+ functionName = "sum";
+ } else if (ctx.aggFunction().AVG() != null) {
+ functionName = "avg";
+ }
+
+ return new FunctionCall(functionName,
+ new FunctionParams(ctx.aggFunction().DISTINCT() != null,
+ expression(ctx.aggFunction().expression())));
+ }
+
@Override
public Expression visitDereference(DereferenceContext ctx) {
Expression e = expression(ctx.base);
diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/NodeType.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/NodeType.java
index 2ad0894766..50a1c1858b 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/NodeType.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/NodeType.java
@@ -44,6 +44,21 @@ public enum NodeType {
NOT,
ALIAS,
COMPOUND,
+ AND,
+ OR,
+ BETWEEN,
+ MULTIPLY,
+ DIVIDE,
+ MOD,
+ INT_DIVIDE,
+ ADD,
+ SUBTRACT,
+ BITAND,
+ BITOR,
+ BITXOR,
+ BITNOT,
+ FACTORIAL,
+ FUNCTIONCALL,
// pattern
PATTERN
diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/analysis/FunctionParams.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/analysis/FunctionParams.java
new file mode 100644
index 0000000000..f2f3a25ae0
--- /dev/null
+++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/analysis/FunctionParams.java
@@ -0,0 +1,83 @@
+// 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.analysis;
+
+import org.apache.doris.nereids.trees.expressions.Expression;
+
+import com.google.common.collect.Lists;
+
+import java.util.List;
+import java.util.Objects;
+
+/**
+ * Function's Params.
+ */
+public class FunctionParams {
+ private boolean isStar;
+ private List<Expression> expression;
+ private boolean isDistinct;
+
+ /**
+ * Constructor for FunctionParams.
+ */
+ public FunctionParams(boolean isDistinct, List<Expression> exprs) {
+ isStar = false;
+ this.isDistinct = isDistinct;
+ this.expression = exprs;
+ }
+
+ public FunctionParams(boolean isDistinct, Expression expression) {
+ this(isDistinct, Lists.newArrayList(expression));
+ }
+
+
+ // c'tor for non-star, non-distinct params
+ public FunctionParams(Expression exprs) {
+ this(false, exprs);
+ }
+
+ // c'tor for <agg>(*)
+ private FunctionParams() {
+ expression = null;
+ isStar = true;
+ isDistinct = false;
+ }
+
+ public List<Expression> getExpression() {
+ return expression;
+ }
+
+ public boolean isStar() {
+ return isStar;
+ }
+
+ public boolean isDistinct() {
+ return isDistinct;
+ }
+
+ @Override
+ public int hashCode() {
+ int result = 31 * Boolean.hashCode(isStar) + Boolean.hashCode(isDistinct);
+ if (expression != null) {
+ for (Expression expr : expression) {
+ result = 31 * result + Objects.hashCode(expr);
+ }
+ }
+ return result;
+ }
+}
diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/NodeType.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/Add.java
similarity index 60%
copy from fe/fe-core/src/main/java/org/apache/doris/nereids/trees/NodeType.java
copy to fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/Add.java
index 2ad0894766..db20391bd4 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/NodeType.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/Add.java
@@ -15,37 +15,20 @@
// specific language governing permissions and limitations
// under the License.
-package org.apache.doris.nereids.trees;
+package org.apache.doris.nereids.trees.expressions;
/**
- * Types for all TreeNode in Nereids, include Plan and Expression.
+ * Add Expression.
*/
-public enum NodeType {
- // plan
- LOGICAL,
- PHYSICAL,
- // group plan
- GROUP,
+public class Add<LEFT_CHILD_TYPE extends Expression, RIGHT_CHILD_TYPE extends Expression>
+ extends Arithmetic implements BinaryExpression<LEFT_CHILD_TYPE, RIGHT_CHILD_TYPE> {
+ public Add(LEFT_CHILD_TYPE left, RIGHT_CHILD_TYPE right) {
+ super(ArithmeticOperator.ADD, left, right);
+ }
- // expressions
- EXPRESSION,
- UNBOUND_ALIAS,
- UNBOUND_SLOT,
- UNBOUND_STAR,
- LITERAL,
- SLOT_REFERENCE,
- COMPARISON_PREDICATE,
- EQUAL_TO,
- LESS_THAN,
- GREATER_THAN,
- LESS_THAN_EQUAL,
- GREATER_THAN_EQUAL,
- NULL_SAFE_EQUAL,
- NOT,
- ALIAS,
- COMPOUND,
-
- // pattern
- PATTERN
- ;
+ @Override
+ public String sql() {
+ return left().sql() + ' ' + getArithOperator().toString()
+ + ' ' + right().sql();
+ }
}
diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/NodeType.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/And.java
similarity index 58%
copy from fe/fe-core/src/main/java/org/apache/doris/nereids/trees/NodeType.java
copy to fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/And.java
index 2ad0894766..3da0626bad 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/NodeType.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/And.java
@@ -15,37 +15,22 @@
// specific language governing permissions and limitations
// under the License.
-package org.apache.doris.nereids.trees;
+package org.apache.doris.nereids.trees.expressions;
+
+import org.apache.doris.nereids.trees.NodeType;
/**
- * Types for all TreeNode in Nereids, include Plan and Expression.
+ * And predicate expression.
*/
-public enum NodeType {
- // plan
- LOGICAL,
- PHYSICAL,
- // group plan
- GROUP,
-
- // expressions
- EXPRESSION,
- UNBOUND_ALIAS,
- UNBOUND_SLOT,
- UNBOUND_STAR,
- LITERAL,
- SLOT_REFERENCE,
- COMPARISON_PREDICATE,
- EQUAL_TO,
- LESS_THAN,
- GREATER_THAN,
- LESS_THAN_EQUAL,
- GREATER_THAN_EQUAL,
- NULL_SAFE_EQUAL,
- NOT,
- ALIAS,
- COMPOUND,
-
- // pattern
- PATTERN
- ;
+public class And<LEFT_CHILD_TYPE extends Expression, RIGHT_CHILD_TYPE extends Expression>
+ extends CompoundPredicate<LEFT_CHILD_TYPE, RIGHT_CHILD_TYPE> {
+ /**
+ * Desc: Constructor for CompoundPredicate.
+ *
+ * @param left left child of comparison predicate
+ * @param right right child of comparison predicate
+ */
+ public And(LEFT_CHILD_TYPE left, RIGHT_CHILD_TYPE right) {
+ super(NodeType.AND, left, right);
+ }
}
diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/Arithmetic.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/Arithmetic.java
new file mode 100644
index 0000000000..9f106ee07a
--- /dev/null
+++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/Arithmetic.java
@@ -0,0 +1,134 @@
+// 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.expressions;
+
+
+import org.apache.doris.nereids.trees.NodeType;
+import org.apache.doris.thrift.TExprOpcode;
+
+/**
+ * All arithmetic operator.
+ */
+public class Arithmetic extends Expression {
+
+ enum OperatorPosition {
+ BINARY_INFIX,
+ UNARY_PREFIX,
+ UNARY_POSTFIX,
+ }
+
+ /**
+ * All counts as expressions.
+ */
+ @SuppressWarnings("checkstyle:RegexpSingleline")
+ public enum ArithmeticOperator {
+ MULTIPLY("*", "multiply", Arithmetic.OperatorPosition.BINARY_INFIX, TExprOpcode.MULTIPLY),
+ DIVIDE("/", "divide", Arithmetic.OperatorPosition.BINARY_INFIX, TExprOpcode.DIVIDE),
+ MOD("%", "mod", Arithmetic.OperatorPosition.BINARY_INFIX, TExprOpcode.MOD),
+ ADD("+", "add", Arithmetic.OperatorPosition.BINARY_INFIX, TExprOpcode.ADD),
+ SUBTRACT("-", "subtract", Arithmetic.OperatorPosition.BINARY_INFIX, TExprOpcode.SUBTRACT),
+ //TODO: The following functions will be added later.
+ BITAND("&", "bitand", Arithmetic.OperatorPosition.BINARY_INFIX, TExprOpcode.BITAND),
+ BITOR("|", "bitor", Arithmetic.OperatorPosition.BINARY_INFIX, TExprOpcode.BITOR),
+ BITXOR("^", "bitxor", Arithmetic.OperatorPosition.BINARY_INFIX, TExprOpcode.BITXOR),
+ BITNOT("~", "bitnot", Arithmetic.OperatorPosition.UNARY_PREFIX, TExprOpcode.BITNOT);
+
+ private final String description;
+ private final String name;
+ private final Arithmetic.OperatorPosition pos;
+ private final TExprOpcode opcode;
+
+ ArithmeticOperator(String description, String name, Arithmetic.OperatorPosition pos, TExprOpcode opcode) {
+ this.description = description;
+ this.name = name;
+ this.pos = pos;
+ this.opcode = opcode;
+ }
+
+ @Override
+ public String toString() {
+ return description;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public Arithmetic.OperatorPosition getPos() {
+ return pos;
+ }
+
+ public TExprOpcode getOpcode() {
+ return opcode;
+ }
+
+ public boolean isUnary() {
+ return pos == Arithmetic.OperatorPosition.UNARY_PREFIX
+ || pos == Arithmetic.OperatorPosition.UNARY_POSTFIX;
+ }
+
+ public boolean isBinary() {
+ return pos == Arithmetic.OperatorPosition.BINARY_INFIX;
+ }
+ }
+
+ private final ArithmeticOperator op;
+
+ public Arithmetic(ArithmeticOperator op, Expression... children) {
+ super(genNodeType(op), children);
+ this.op = op;
+ }
+
+ public ArithmeticOperator getArithOperator() {
+ return op;
+ }
+
+ private static NodeType genNodeType(ArithmeticOperator op) {
+ switch (op) {
+ case MULTIPLY:
+ return NodeType.MULTIPLY;
+ case DIVIDE:
+ return NodeType.DIVIDE;
+ case MOD:
+ return NodeType.MOD;
+ case ADD:
+ return NodeType.ADD;
+ case SUBTRACT:
+ return NodeType.SUBTRACT;
+ case BITAND:
+ return NodeType.BITAND;
+ case BITOR:
+ return NodeType.BITOR;
+ case BITXOR:
+ return NodeType.BITXOR;
+ case BITNOT:
+ return NodeType.NOT;
+ default:
+ return null;
+ }
+ }
+
+ public <R, C> R accept(ExpressionVisitor<R, C> visitor, C context) {
+ return visitor.visitArithmetic(this, context);
+ }
+
+ @Override
+ public String sql() {
+ return null;
+ }
+}
diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/BetweenPredicate.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/BetweenPredicate.java
new file mode 100644
index 0000000000..e4c875b0ef
--- /dev/null
+++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/BetweenPredicate.java
@@ -0,0 +1,77 @@
+// 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.expressions;
+
+import org.apache.doris.nereids.exceptions.UnboundException;
+import org.apache.doris.nereids.trees.NodeType;
+import org.apache.doris.nereids.types.BooleanType;
+import org.apache.doris.nereids.types.DataType;
+
+/**
+ * Between predicate expression.
+ */
+public class BetweenPredicate extends Expression {
+
+ private Expression compareExpr;
+ private Expression lowerBound;
+ private Expression upperBound;
+ /**
+ * Constructor of ComparisonPredicate.
+ *
+ * @param compareExpr compare of expression
+ * @param lowerBound left child of between predicate
+ * @param upperBound right child of between predicate
+ */
+
+ public BetweenPredicate(Expression compareExpr, Expression lowerBound,
+ Expression upperBound) {
+ super(NodeType.BETWEEN, compareExpr, lowerBound, upperBound);
+ this.compareExpr = compareExpr;
+ this.lowerBound = lowerBound;
+ this.upperBound = upperBound;
+ }
+
+ @Override
+ public DataType getDataType() throws UnboundException {
+ return BooleanType.INSTANCE;
+ }
+
+ @Override
+ public String sql() {
+ return compareExpr.sql()
+ + " BETWEEN "
+ + lowerBound.sql() + " AND " + upperBound.sql();
+ }
+
+ public <R, C> R accept(ExpressionVisitor<R, C> visitor, C context) {
+ return visitor.visitBetweenPredicate(this, context);
+ }
+
+ public Expression getCompareExpr() {
+ return compareExpr;
+ }
+
+ public Expression getLowerBound() {
+ return lowerBound;
+ }
+
+ public Expression getUpperBound() {
+ return upperBound;
+ }
+
+}
diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/ComparisonPredicate.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/ComparisonPredicate.java
index eb301b4969..a0b495baf8 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/ComparisonPredicate.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/ComparisonPredicate.java
@@ -48,7 +48,8 @@ public abstract class ComparisonPredicate<LEFT_CHILD_TYPE extends Expression, RI
@Override
public String sql() {
- return toString();
+ String nodeType = getType().toString();
+ return left().sql() + ' ' + nodeType + ' ' + right().sql();
}
public <R, C> R accept(ExpressionVisitor<R, C> visitor, C context) {
diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/FunctionCall.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/CompoundPredicate.java
similarity index 50%
copy from fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/FunctionCall.java
copy to fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/CompoundPredicate.java
index 17cc075e8f..fbb3faa50e 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/FunctionCall.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/CompoundPredicate.java
@@ -17,50 +17,33 @@
package org.apache.doris.nereids.trees.expressions;
-import org.apache.doris.analysis.FunctionName;
-import org.apache.doris.catalog.Function;
import org.apache.doris.nereids.trees.NodeType;
-import java.util.Arrays;
-import java.util.List;
-import java.util.stream.Collectors;
-
/**
- * Temp definition of FunctionCallExpression.
+ * Compound predicate expression.
+ * Such as &&,||,AND,OR.
*/
-public class FunctionCall extends Expression {
-
- private final FunctionName functionName;
-
- private final List<Expression> params;
-
- private final Function fn;
+public class CompoundPredicate<LEFT_CHILD_TYPE extends Expression, RIGHT_CHILD_TYPE extends Expression>
+ extends Expression implements BinaryExpression<LEFT_CHILD_TYPE, RIGHT_CHILD_TYPE> {
/**
- * Constructor of FunctionCallExpression.
+ * Desc: Constructor for CompoundPredicate.
+ *
+ * @param type type of expression
+ * @param left left child of comparison predicate
+ * @param right right child of comparison predicate
*/
- public FunctionCall(FunctionName functionName,
- Function fn, Expression... children) {
- super(NodeType.EXPRESSION, children);
- this.functionName = functionName;
- this.params = Arrays.stream(children).collect(Collectors.toList());
- this.fn = fn;
- }
-
- public FunctionName getFunctionName() {
- return functionName;
- }
-
- public List<Expression> getParams() {
- return params;
+ public CompoundPredicate(NodeType type, LEFT_CHILD_TYPE left, RIGHT_CHILD_TYPE right) {
+ super(type, left, right);
}
- public Function getFn() {
- return fn;
+ @Override
+ public String sql() {
+ String nodeType = getType().toString();
+ return left().sql() + ' ' + nodeType + ' ' + right().sql();
}
- @Override
public <R, C> R accept(ExpressionVisitor<R, C> visitor, C context) {
- return visitor.visitFunctionCall(this, context);
+ return visitor.visitCompoundPredicate(this, context);
}
}
diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/NodeType.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/Divide.java
similarity index 60%
copy from fe/fe-core/src/main/java/org/apache/doris/nereids/trees/NodeType.java
copy to fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/Divide.java
index 2ad0894766..e921557d09 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/NodeType.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/Divide.java
@@ -15,37 +15,20 @@
// specific language governing permissions and limitations
// under the License.
-package org.apache.doris.nereids.trees;
+package org.apache.doris.nereids.trees.expressions;
/**
- * Types for all TreeNode in Nereids, include Plan and Expression.
+ * Divide Expression.
*/
-public enum NodeType {
- // plan
- LOGICAL,
- PHYSICAL,
- // group plan
- GROUP,
+public class Divide<LEFT_CHILD_TYPE extends Expression, RIGHT_CHILD_TYPE extends Expression>
+ extends Arithmetic implements BinaryExpression<LEFT_CHILD_TYPE, RIGHT_CHILD_TYPE> {
+ public Divide(LEFT_CHILD_TYPE left, RIGHT_CHILD_TYPE right) {
+ super(ArithmeticOperator.DIVIDE, left, right);
+ }
- // expressions
- EXPRESSION,
- UNBOUND_ALIAS,
- UNBOUND_SLOT,
- UNBOUND_STAR,
- LITERAL,
- SLOT_REFERENCE,
- COMPARISON_PREDICATE,
- EQUAL_TO,
- LESS_THAN,
- GREATER_THAN,
- LESS_THAN_EQUAL,
- GREATER_THAN_EQUAL,
- NULL_SAFE_EQUAL,
- NOT,
- ALIAS,
- COMPOUND,
-
- // pattern
- PATTERN
- ;
+ @Override
+ public String sql() {
+ return left().sql() + ' ' + getArithOperator().toString()
+ + ' ' + right().sql();
+ }
}
diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/Expression.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/Expression.java
index 91b06bd484..53b6aea8ee 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/Expression.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/Expression.java
@@ -81,4 +81,5 @@ public abstract class Expression extends AbstractTreeNode<Expression> {
}
return false;
}
+
}
diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/ExpressionVisitor.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/ExpressionVisitor.java
index 7b40fb1ba3..943762537f 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/ExpressionVisitor.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/ExpressionVisitor.java
@@ -81,6 +81,19 @@ public abstract class ExpressionVisitor<R, C> {
return visit(function, context);
}
+ public R visitBetweenPredicate(BetweenPredicate betweenPredicate, C context) {
+ return visit(betweenPredicate, context);
+ }
+
+ public R visitCompoundPredicate(CompoundPredicate compoundPredicate, C context) {
+ return visit(compoundPredicate, context);
+ }
+
+ public R visitArithmetic(Arithmetic arithmetic, C context) {
+ return visit(arithmetic, context);
+ }
+
+
/* ********************************************************************************************
* Unbound expressions
* ********************************************************************************************/
diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/FunctionCall.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/FunctionCall.java
index 17cc075e8f..db797c5ef9 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/FunctionCall.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/FunctionCall.java
@@ -18,48 +18,32 @@
package org.apache.doris.nereids.trees.expressions;
import org.apache.doris.analysis.FunctionName;
-import org.apache.doris.catalog.Function;
import org.apache.doris.nereids.trees.NodeType;
-
-import java.util.Arrays;
-import java.util.List;
-import java.util.stream.Collectors;
+import org.apache.doris.nereids.trees.analysis.FunctionParams;
/**
- * Temp definition of FunctionCallExpression.
+ * Logical FunctionCall Expression.
*/
public class FunctionCall extends Expression {
- private final FunctionName functionName;
-
- private final List<Expression> params;
+ private FunctionName fnName;
- private final Function fn;
-
- /**
- * Constructor of FunctionCallExpression.
- */
- public FunctionCall(FunctionName functionName,
- Function fn, Expression... children) {
- super(NodeType.EXPRESSION, children);
- this.functionName = functionName;
- this.params = Arrays.stream(children).collect(Collectors.toList());
- this.fn = fn;
- }
+ private FunctionParams fnParams;
- public FunctionName getFunctionName() {
- return functionName;
+ private FunctionCall(FunctionName functionName, FunctionParams functionParams) {
+ super(NodeType.FUNCTIONCALL, functionParams.getExpression().toArray(new Expression[0]));
+ this.fnName = functionName;
+ this.fnParams = functionParams;
}
- public List<Expression> getParams() {
- return params;
+ public FunctionCall(String functionName, Expression params) {
+ this(new FunctionName(functionName), new FunctionParams(false, params));
}
- public Function getFn() {
- return fn;
+ public FunctionCall(String functionName, FunctionParams functionParams) {
+ this(new FunctionName(functionName), functionParams);
}
- @Override
public <R, C> R accept(ExpressionVisitor<R, C> visitor, C context) {
return visitor.visitFunctionCall(this, context);
}
diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/Literal.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/Literal.java
index 2152a9a3cb..912b72705e 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/Literal.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/Literal.java
@@ -31,6 +31,7 @@ import java.util.Objects;
/**
* All data type literal expression in Nereids.
+ * TODO: Increase the implementation of sub expression. such as Integer.
*/
public class Literal extends Expression implements LeafExpression {
private final DataType dataType;
@@ -108,7 +109,7 @@ public class Literal extends Expression implements LeafExpression {
@Override
public String sql() {
- return null;
+ return value.toString();
}
@Override
diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/NodeType.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/Mod.java
similarity index 60%
copy from fe/fe-core/src/main/java/org/apache/doris/nereids/trees/NodeType.java
copy to fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/Mod.java
index 2ad0894766..f5210f89fd 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/NodeType.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/Mod.java
@@ -15,37 +15,20 @@
// specific language governing permissions and limitations
// under the License.
-package org.apache.doris.nereids.trees;
+package org.apache.doris.nereids.trees.expressions;
/**
- * Types for all TreeNode in Nereids, include Plan and Expression.
+ * Mod Expression.
*/
-public enum NodeType {
- // plan
- LOGICAL,
- PHYSICAL,
- // group plan
- GROUP,
+public class Mod<LEFT_CHILD_TYPE extends Expression, RIGHT_CHILD_TYPE extends Expression>
+ extends Arithmetic implements BinaryExpression<LEFT_CHILD_TYPE, RIGHT_CHILD_TYPE> {
+ public Mod(LEFT_CHILD_TYPE left, RIGHT_CHILD_TYPE right) {
+ super(ArithmeticOperator.MOD, left, right);
+ }
- // expressions
- EXPRESSION,
- UNBOUND_ALIAS,
- UNBOUND_SLOT,
- UNBOUND_STAR,
- LITERAL,
- SLOT_REFERENCE,
- COMPARISON_PREDICATE,
- EQUAL_TO,
- LESS_THAN,
- GREATER_THAN,
- LESS_THAN_EQUAL,
- GREATER_THAN_EQUAL,
- NULL_SAFE_EQUAL,
- NOT,
- ALIAS,
- COMPOUND,
-
- // pattern
- PATTERN
- ;
+ @Override
+ public String sql() {
+ return left().sql() + ' ' + getArithOperator().toString()
+ + ' ' + right().sql();
+ }
}
diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/NodeType.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/Multiply.java
similarity index 59%
copy from fe/fe-core/src/main/java/org/apache/doris/nereids/trees/NodeType.java
copy to fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/Multiply.java
index 2ad0894766..7852053dc3 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/NodeType.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/Multiply.java
@@ -15,37 +15,21 @@
// specific language governing permissions and limitations
// under the License.
-package org.apache.doris.nereids.trees;
+package org.apache.doris.nereids.trees.expressions;
/**
- * Types for all TreeNode in Nereids, include Plan and Expression.
+ * Multiply Expression.
*/
-public enum NodeType {
- // plan
- LOGICAL,
- PHYSICAL,
- // group plan
- GROUP,
+public class Multiply<LEFT_CHILD_TYPE extends Expression, RIGHT_CHILD_TYPE extends Expression>
+ extends Arithmetic implements BinaryExpression<LEFT_CHILD_TYPE, RIGHT_CHILD_TYPE> {
- // expressions
- EXPRESSION,
- UNBOUND_ALIAS,
- UNBOUND_SLOT,
- UNBOUND_STAR,
- LITERAL,
- SLOT_REFERENCE,
- COMPARISON_PREDICATE,
- EQUAL_TO,
- LESS_THAN,
- GREATER_THAN,
- LESS_THAN_EQUAL,
- GREATER_THAN_EQUAL,
- NULL_SAFE_EQUAL,
- NOT,
- ALIAS,
- COMPOUND,
+ public Multiply(LEFT_CHILD_TYPE left, RIGHT_CHILD_TYPE right) {
+ super(ArithmeticOperator.MULTIPLY, left, right);
+ }
- // pattern
- PATTERN
- ;
+ @Override
+ public String sql() {
+ return left().sql() + ' ' + getArithOperator().toString()
+ + ' ' + right().sql();
+ }
}
diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/NodeType.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/Or.java
similarity index 58%
copy from fe/fe-core/src/main/java/org/apache/doris/nereids/trees/NodeType.java
copy to fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/Or.java
index 2ad0894766..eddc88126d 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/NodeType.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/Or.java
@@ -15,37 +15,22 @@
// specific language governing permissions and limitations
// under the License.
-package org.apache.doris.nereids.trees;
+package org.apache.doris.nereids.trees.expressions;
+
+import org.apache.doris.nereids.trees.NodeType;
/**
- * Types for all TreeNode in Nereids, include Plan and Expression.
+ * Or predicate expression.
*/
-public enum NodeType {
- // plan
- LOGICAL,
- PHYSICAL,
- // group plan
- GROUP,
-
- // expressions
- EXPRESSION,
- UNBOUND_ALIAS,
- UNBOUND_SLOT,
- UNBOUND_STAR,
- LITERAL,
- SLOT_REFERENCE,
- COMPARISON_PREDICATE,
- EQUAL_TO,
- LESS_THAN,
- GREATER_THAN,
- LESS_THAN_EQUAL,
- GREATER_THAN_EQUAL,
- NULL_SAFE_EQUAL,
- NOT,
- ALIAS,
- COMPOUND,
-
- // pattern
- PATTERN
- ;
+public class Or<LEFT_CHILD_TYPE extends Expression, RIGHT_CHILD_TYPE extends Expression>
+ extends CompoundPredicate<LEFT_CHILD_TYPE, RIGHT_CHILD_TYPE> {
+ /**
+ * Desc: Constructor for CompoundPredicate.
+ *
+ * @param left left child of comparison predicate
+ * @param right right child of comparison predicate
+ */
+ public Or(LEFT_CHILD_TYPE left, RIGHT_CHILD_TYPE right) {
+ super(NodeType.OR, left, right);
+ }
}
diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/NodeType.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/Subtract.java
similarity index 59%
copy from fe/fe-core/src/main/java/org/apache/doris/nereids/trees/NodeType.java
copy to fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/Subtract.java
index 2ad0894766..c4944709c0 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/NodeType.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/Subtract.java
@@ -15,37 +15,20 @@
// specific language governing permissions and limitations
// under the License.
-package org.apache.doris.nereids.trees;
+package org.apache.doris.nereids.trees.expressions;
/**
- * Types for all TreeNode in Nereids, include Plan and Expression.
+ * Subtract Expression. BinaryExpression.
*/
-public enum NodeType {
- // plan
- LOGICAL,
- PHYSICAL,
- // group plan
- GROUP,
+public class Subtract<LEFT_CHILD_TYPE extends Expression, RIGHT_CHILD_TYPE extends Expression>
+ extends Arithmetic implements BinaryExpression<LEFT_CHILD_TYPE, RIGHT_CHILD_TYPE> {
+ public Subtract(LEFT_CHILD_TYPE left, RIGHT_CHILD_TYPE right) {
+ super(ArithmeticOperator.SUBTRACT, left, right);
+ }
- // expressions
- EXPRESSION,
- UNBOUND_ALIAS,
- UNBOUND_SLOT,
- UNBOUND_STAR,
- LITERAL,
- SLOT_REFERENCE,
- COMPARISON_PREDICATE,
- EQUAL_TO,
- LESS_THAN,
- GREATER_THAN,
- LESS_THAN_EQUAL,
- GREATER_THAN_EQUAL,
- NULL_SAFE_EQUAL,
- NOT,
- ALIAS,
- COMPOUND,
-
- // pattern
- PATTERN
- ;
+ @Override
+ public String sql() {
+ return left().sql() + ' ' + getArithOperator().toString()
+ + ' ' + right().sql();
+ }
}
diff --git a/fe/fe-core/src/test/java/org/apache/doris/nereids/trees/expressions/ExpressionParserTest.java b/fe/fe-core/src/test/java/org/apache/doris/nereids/trees/expressions/ExpressionParserTest.java
new file mode 100644
index 0000000000..987760f6bf
--- /dev/null
+++ b/fe/fe-core/src/test/java/org/apache/doris/nereids/trees/expressions/ExpressionParserTest.java
@@ -0,0 +1,137 @@
+// 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.expressions;
+
+import org.apache.doris.nereids.parser.SqlParser;
+import org.apache.doris.nereids.trees.TreeNode;
+
+import org.junit.Test;
+
+public class ExpressionParserTest {
+ private static final SqlParser PARSER = new SqlParser();
+
+ private void assertSql(String sql) throws Exception {
+ TreeNode treeNode = PARSER.parse(sql);
+ System.out.println(treeNode.toString());
+ }
+
+ private void assertExpr(String expr) {
+ Expression expression = PARSER.createExpression(expr);
+ System.out.println(expression.sql());
+ }
+
+ @Test
+ public void testSqlBetweenPredicate() throws Exception {
+ String sql = "select * from test1 where d1 between 1 and 2";
+ assertSql(sql);
+ }
+
+ @Test
+ public void testExprBetweenPredicate() {
+ String sql = "c BETWEEN a AND b";
+ assertExpr(sql);
+ }
+
+ @Test
+ public void testSqlAnd() throws Exception {
+ String sql = "select * from test1 where a > 1 and b > 1";
+ TreeNode treeNode = PARSER.parse(sql);
+ System.out.println(treeNode);
+ }
+
+ @Test
+ public void testExprAnd() {
+ String expr = "a AND b";
+ assertExpr(expr);
+ }
+
+ @Test
+ public void testExprMultiAnd() {
+ String expr = "a AND b AND c AND d";
+ assertExpr(expr);
+ }
+
+ @Test
+ public void testExprOr() {
+ String expr = "a OR b";
+ assertExpr(expr);
+ }
+
+ @Test
+ public void testExprMultiOr() {
+ String expr = "a OR b OR c OR d";
+ assertExpr(expr);
+ }
+
+ @Test
+ public void testExprArithmetic() {
+ String multiply = "1 * 2";
+ assertExpr(multiply);
+
+ String divide = "3 / 2";
+ assertExpr(divide);
+
+ String mod = "5 % 3";
+ assertExpr(mod);
+
+ String add = "3 + 3";
+ assertExpr(add);
+
+ String subtract = "3 - 2";
+ assertExpr(subtract);
+ }
+
+ @Test
+ public void testSqlFunction() throws Exception {
+ String sum = "select sum(a) from test1";
+ assertSql(sum);
+
+ String sumWithAs = "select sum(a) as b from test1";
+ assertSql(sumWithAs);
+
+ String sumAndAvg = "select sum(a),avg(b) from test1";
+ assertSql(sumAndAvg);
+ }
+
+ @Test
+ public void testGroupByClause() throws Exception {
+
+ String groupBy = "select a from test group by a";
+ assertSql(groupBy);
+
+ String groupByWithFun1 = "select sum(a), b from test1 group by b";
+ assertSql(groupByWithFun1);
+
+
+ String groupByWithFun2 = "select sum(a), b, c+1 from test1 group by b, c";
+ assertSql(groupByWithFun2);
+
+ String groupBySum = "select k1+k2 from test group by k1+k2";
+ assertSql(groupBySum);
+ }
+
+ @Test
+ public void testSortClause() throws Exception {
+
+ String sort = "select a from test order by c, d";
+ assertSql(sort);
+
+ String sort1 = "select a from test order by 1";
+ assertSql(sort1);
+ }
+}
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@doris.apache.org
For additional commands, e-mail: commits-help@doris.apache.org