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/12/13 04:58:47 UTC

[doris] branch master updated: [feature](Nereids) add binary & unary arithmetic expression (#14867)

This is an automated email from the ASF dual-hosted git repository.

morrysnow 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 3caa9a19cc [feature](Nereids) add binary & unary arithmetic expression (#14867)
3caa9a19cc is described below

commit 3caa9a19cc2969cfbb728272730b11944674d7e3
Author: minghong <en...@gmail.com>
AuthorDate: Tue Dec 13 12:58:40 2022 +0800

    [feature](Nereids) add binary & unary arithmetic expression (#14867)
    
    binary arithmetic expression: div, ^, |, &, %
    unary arithmetic expression: ~, +1
---
 .../antlr4/org/apache/doris/nereids/DorisLexer.g4  |  1 +
 .../antlr4/org/apache/doris/nereids/DorisParser.g4 |  6 +-
 .../glue/translator/ExpressionTranslator.java      |  8 +++
 .../doris/nereids/parser/LogicalPlanBuilder.java   | 19 +++++-
 .../expression/rewrite/rules/TypeCoercion.java     | 14 ++++
 .../doris/nereids/trees/expressions/BitAnd.java    | 53 ++++++++++++++++
 .../doris/nereids/trees/expressions/BitNot.java    | 60 ++++++++++++++++++
 .../doris/nereids/trees/expressions/BitOr.java     | 53 ++++++++++++++++
 .../doris/nereids/trees/expressions/BitXor.java    | 53 ++++++++++++++++
 .../nereids/trees/expressions/UnaryArithmetic.java | 55 ++++++++++++++++
 .../nereids/trees/expressions/UnaryOperator.java   | 74 ++++++++++++++++++++++
 .../expressions/visitor/ExpressionVisitor.java     | 30 +++++++++
 .../glue/translator/ExpressionTranslatorTest.java  | 39 ++++++++++++
 .../nereids_syntax_p0/unary_binary_arithmetic.out  | 52 +++++++++++++++
 .../unary_binary_arithmetic.groovy                 | 48 ++++++++++++++
 15 files changed, 561 insertions(+), 4 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 87a452b699..5f2628e656 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
@@ -166,6 +166,7 @@ DIRECTORIES: 'DIRECTORIES';
 DIRECTORY: 'DIRECTORY';
 DISTINCT: 'DISTINCT';
 DISTRIBUTE: 'DISTRIBUTE';
+DIV: 'DIV';
 DROP: 'DROP';
 ELSE: 'ELSE';
 END: 'END';
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 19543bce74..8e36202897 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
@@ -257,9 +257,10 @@ predicate
 
 valueExpression
     : primaryExpression                                                                      #valueExpressionDefault
-    | operator=(MINUS | PLUS) valueExpression                                                #arithmeticUnary
+    | operator=(MINUS | PLUS | TILDE) valueExpression                                        #arithmeticUnary
     | left=valueExpression operator=(ASTERISK | SLASH | PERCENT) right=valueExpression       #arithmeticBinary
-    | left=valueExpression operator=(PLUS | MINUS) right=valueExpression                     #arithmeticBinary
+    | left=valueExpression operator=(PLUS | MINUS | DIV | HAT | PIPE | AMPERSAND)
+                           right=valueExpression                                             #arithmeticBinary
     | left=valueExpression comparisonOperator right=valueExpression                          #comparison
     ;
 
@@ -704,6 +705,7 @@ nonReserved
     | DIRECTORY
     | DISTINCT
     | DISTRIBUTE
+    | DIV
     | DROP
     | ELSE
     | END
diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/glue/translator/ExpressionTranslator.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/glue/translator/ExpressionTranslator.java
index 00069ff284..d628660c9b 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/nereids/glue/translator/ExpressionTranslator.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/glue/translator/ExpressionTranslator.java
@@ -61,6 +61,7 @@ import org.apache.doris.nereids.trees.expressions.Or;
 import org.apache.doris.nereids.trees.expressions.Regexp;
 import org.apache.doris.nereids.trees.expressions.SlotReference;
 import org.apache.doris.nereids.trees.expressions.TimestampArithmetic;
+import org.apache.doris.nereids.trees.expressions.UnaryArithmetic;
 import org.apache.doris.nereids.trees.expressions.VirtualSlotReference;
 import org.apache.doris.nereids.trees.expressions.WhenClause;
 import org.apache.doris.nereids.trees.expressions.functions.agg.AggregateFunction;
@@ -346,6 +347,13 @@ public class ExpressionTranslator extends DefaultExpressionVisitor<Expr, PlanTra
                 binaryArithmetic.child(1).accept(this, context));
     }
 
+    @Override
+    public Expr visitUnaryArithmetic(UnaryArithmetic unaryArithmetic, PlanTranslatorContext context) {
+        return new ArithmeticExpr(unaryArithmetic.getLegacyOperator(),
+                unaryArithmetic.child().accept(this, context), null);
+
+    }
+
     @Override
     public Expr visitTimestampArithmetic(TimestampArithmetic arithmetic, PlanTranslatorContext context) {
         if (arithmetic.getFuncName() == null) {
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 f824f0e875..340962fbfa 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
@@ -103,6 +103,10 @@ import org.apache.doris.nereids.properties.SelectHint;
 import org.apache.doris.nereids.trees.expressions.Add;
 import org.apache.doris.nereids.trees.expressions.And;
 import org.apache.doris.nereids.trees.expressions.Between;
+import org.apache.doris.nereids.trees.expressions.BitAnd;
+import org.apache.doris.nereids.trees.expressions.BitNot;
+import org.apache.doris.nereids.trees.expressions.BitOr;
+import org.apache.doris.nereids.trees.expressions.BitXor;
 import org.apache.doris.nereids.trees.expressions.CaseWhen;
 import org.apache.doris.nereids.trees.expressions.Cast;
 import org.apache.doris.nereids.trees.expressions.Divide;
@@ -517,12 +521,15 @@ public class LogicalPlanBuilder extends DorisParserBaseVisitor<Object> {
     @Override
     public Expression visitArithmeticUnary(ArithmeticUnaryContext ctx) {
         return ParserUtils.withOrigin(ctx, () -> {
-            Expression e = getExpression(ctx);
+            Expression e = typedVisit(ctx.valueExpression());
             switch (ctx.operator.getType()) {
                 case DorisParser.PLUS:
                     return e;
                 case DorisParser.MINUS:
-                    // TODO: Add single operator subtraction
+                    IntegerLiteral zero = new IntegerLiteral(0);
+                    return new Subtract(zero, e);
+                case DorisParser.TILDE:
+                    return new BitNot(e);
                 default:
                     throw new ParseException("Unsupported arithmetic unary type: " + ctx.operator.getText(), ctx);
             }
@@ -569,6 +576,14 @@ public class LogicalPlanBuilder extends DorisParserBaseVisitor<Object> {
                         return new Add(left, right);
                     case DorisParser.MINUS:
                         return new Subtract(left, right);
+                    case DorisParser.DIV:
+                        return new Divide(left, right);
+                    case DorisParser.HAT:
+                        return new BitXor(left, right);
+                    case DorisParser.PIPE:
+                        return new BitOr(left, right);
+                    case DorisParser.AMPERSAND:
+                        return new BitAnd(left, right);
                     default:
                         throw new ParseException(
                                 "Unsupported arithmetic binary type: " + ctx.operator.getText(), ctx);
diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/expression/rewrite/rules/TypeCoercion.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/expression/rewrite/rules/TypeCoercion.java
index 0670eb2955..cee94f8af6 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/expression/rewrite/rules/TypeCoercion.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/expression/rewrite/rules/TypeCoercion.java
@@ -18,15 +18,19 @@
 package org.apache.doris.nereids.rules.expression.rewrite.rules;
 
 import org.apache.doris.analysis.ArithmeticExpr.Operator;
+import org.apache.doris.catalog.PrimitiveType;
 import org.apache.doris.nereids.annotation.Developing;
 import org.apache.doris.nereids.rules.expression.rewrite.AbstractExpressionRewriteRule;
 import org.apache.doris.nereids.rules.expression.rewrite.ExpressionRewriteContext;
 import org.apache.doris.nereids.trees.expressions.BinaryOperator;
+import org.apache.doris.nereids.trees.expressions.BitNot;
 import org.apache.doris.nereids.trees.expressions.CaseWhen;
+import org.apache.doris.nereids.trees.expressions.Cast;
 import org.apache.doris.nereids.trees.expressions.Divide;
 import org.apache.doris.nereids.trees.expressions.Expression;
 import org.apache.doris.nereids.trees.expressions.InPredicate;
 import org.apache.doris.nereids.trees.expressions.typecoercion.ImplicitCastInputTypes;
+import org.apache.doris.nereids.types.BigIntType;
 import org.apache.doris.nereids.types.DataType;
 import org.apache.doris.nereids.types.DoubleType;
 import org.apache.doris.nereids.types.coercion.AbstractDataType;
@@ -160,6 +164,16 @@ public class TypeCoercion extends AbstractExpressionRewriteRule {
                 .orElse(newInPredicate);
     }
 
+    @Override
+    public Expression visitBitNot(BitNot bitNot, ExpressionRewriteContext context) {
+        Expression child = rewrite(bitNot.child(), context);
+        if (child.getDataType().toCatalogDataType().getPrimitiveType().ordinal()
+                > PrimitiveType.LARGEINT.ordinal()) {
+            child = new Cast(child, BigIntType.INSTANCE);
+        }
+        return bitNot.withChildren(child);
+    }
+
     /**
      * Do implicit cast for expression's children.
      */
diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/BitAnd.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/BitAnd.java
new file mode 100644
index 0000000000..9dc20dd7a1
--- /dev/null
+++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/BitAnd.java
@@ -0,0 +1,53 @@
+// 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.analysis.ArithmeticExpr.Operator;
+import org.apache.doris.nereids.trees.expressions.visitor.ExpressionVisitor;
+import org.apache.doris.nereids.types.coercion.AbstractDataType;
+import org.apache.doris.nereids.types.coercion.NumericType;
+
+import com.google.common.base.Preconditions;
+
+import java.util.List;
+
+/**
+ * bit xor
+ */
+public class BitAnd extends BinaryArithmetic {
+
+    public BitAnd(Expression left, Expression right) {
+        super(left, right, Operator.BITAND);
+    }
+
+    @Override
+    public Expression withChildren(List<Expression> children) {
+        Preconditions.checkArgument(children.size() == 2);
+        return new BitAnd(children.get(0), children.get(1));
+    }
+
+    @Override
+    public <R, C> R accept(ExpressionVisitor<R, C> visitor, C context) {
+        return visitor.visitBitAnd(this, context);
+    }
+
+    @Override
+    public AbstractDataType inputType() {
+        return NumericType.INSTANCE;
+    }
+}
diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/BitNot.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/BitNot.java
new file mode 100644
index 0000000000..889e7afea2
--- /dev/null
+++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/BitNot.java
@@ -0,0 +1,60 @@
+// 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.analysis.ArithmeticExpr.Operator;
+import org.apache.doris.nereids.exceptions.UnboundException;
+import org.apache.doris.nereids.trees.expressions.visitor.ExpressionVisitor;
+import org.apache.doris.nereids.types.DataType;
+import org.apache.doris.nereids.types.coercion.AbstractDataType;
+import org.apache.doris.nereids.types.coercion.NumericType;
+
+import com.google.common.base.Preconditions;
+
+import java.util.List;
+
+/**
+ * bit not
+ */
+public class BitNot extends UnaryArithmetic {
+
+    public BitNot(Expression child) {
+        super(child, Operator.BITNOT);
+    }
+
+    @Override
+    public Expression withChildren(List<Expression> children) {
+        Preconditions.checkArgument(children.size() == 1);
+        return new BitNot(children.get(0));
+    }
+
+    @Override
+    public DataType getDataType() throws UnboundException {
+        return child().getDataType();
+    }
+
+    @Override
+    public <R, C> R accept(ExpressionVisitor<R, C> visitor, C context) {
+        return visitor.visitBitNot(this, context);
+    }
+
+    @Override
+    public AbstractDataType inputType() {
+        return NumericType.INSTANCE;
+    }
+}
diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/BitOr.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/BitOr.java
new file mode 100644
index 0000000000..f3c1a752b9
--- /dev/null
+++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/BitOr.java
@@ -0,0 +1,53 @@
+// 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.analysis.ArithmeticExpr.Operator;
+import org.apache.doris.nereids.trees.expressions.visitor.ExpressionVisitor;
+import org.apache.doris.nereids.types.coercion.AbstractDataType;
+import org.apache.doris.nereids.types.coercion.NumericType;
+
+import com.google.common.base.Preconditions;
+
+import java.util.List;
+
+/**
+ * bit xor
+ */
+public class BitOr extends BinaryArithmetic {
+
+    public BitOr(Expression left, Expression right) {
+        super(left, right, Operator.BITOR);
+    }
+
+    @Override
+    public Expression withChildren(List<Expression> children) {
+        Preconditions.checkArgument(children.size() == 2);
+        return new BitOr(children.get(0), children.get(1));
+    }
+
+    @Override
+    public <R, C> R accept(ExpressionVisitor<R, C> visitor, C context) {
+        return visitor.visitBitOr(this, context);
+    }
+
+    @Override
+    public AbstractDataType inputType() {
+        return NumericType.INSTANCE;
+    }
+}
diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/BitXor.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/BitXor.java
new file mode 100644
index 0000000000..fe2f0d86d9
--- /dev/null
+++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/BitXor.java
@@ -0,0 +1,53 @@
+// 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.analysis.ArithmeticExpr.Operator;
+import org.apache.doris.nereids.trees.expressions.visitor.ExpressionVisitor;
+import org.apache.doris.nereids.types.coercion.AbstractDataType;
+import org.apache.doris.nereids.types.coercion.NumericType;
+
+import com.google.common.base.Preconditions;
+
+import java.util.List;
+
+/**
+ * bit xor
+ */
+public class BitXor extends BinaryArithmetic {
+
+    public BitXor(Expression left, Expression right) {
+        super(left, right, Operator.BITXOR);
+    }
+
+    @Override
+    public Expression withChildren(List<Expression> children) {
+        Preconditions.checkArgument(children.size() == 2);
+        return new BitXor(children.get(0), children.get(1));
+    }
+
+    @Override
+    public <R, C> R accept(ExpressionVisitor<R, C> visitor, C context) {
+        return visitor.visitBitXor(this, context);
+    }
+
+    @Override
+    public AbstractDataType inputType() {
+        return NumericType.INSTANCE;
+    }
+}
diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/UnaryArithmetic.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/UnaryArithmetic.java
new file mode 100644
index 0000000000..9d624f4b66
--- /dev/null
+++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/UnaryArithmetic.java
@@ -0,0 +1,55 @@
+// 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.analysis.ArithmeticExpr.Operator;
+import org.apache.doris.nereids.exceptions.UnboundException;
+import org.apache.doris.nereids.trees.expressions.functions.PropagateNullable;
+import org.apache.doris.nereids.trees.expressions.visitor.ExpressionVisitor;
+import org.apache.doris.nereids.types.DataType;
+
+/**
+ * binary arithmetic operator. Such as +, -, *, /.
+ */
+public abstract class UnaryArithmetic extends UnaryOperator implements PropagateNullable {
+
+    private final Operator legacyOperator;
+
+    public UnaryArithmetic(Expression child, Operator legacyOperator) {
+        super(child, legacyOperator.toString());
+        this.legacyOperator = legacyOperator;
+    }
+
+    public Operator getLegacyOperator() {
+        return legacyOperator;
+    }
+
+    @Override
+    public DataType getDataType() throws UnboundException {
+        return child().getDataType();
+    }
+
+    @Override
+    public boolean nullable() throws UnboundException {
+        return child().nullable();
+    }
+
+    public <R, C> R accept(ExpressionVisitor<R, C> visitor, C context) {
+        return visitor.visitUnaryArithmetic(this, context);
+    }
+}
diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/UnaryOperator.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/UnaryOperator.java
new file mode 100644
index 0000000000..2e0d6a3d51
--- /dev/null
+++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/UnaryOperator.java
@@ -0,0 +1,74 @@
+// 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.expressions.shape.UnaryExpression;
+import org.apache.doris.nereids.trees.expressions.typecoercion.ExpectsInputTypes;
+import org.apache.doris.nereids.types.coercion.AbstractDataType;
+
+import com.google.common.collect.ImmutableList;
+
+import java.util.List;
+import java.util.Objects;
+
+/**
+ * Abstract for all binary operator, include binary arithmetic, compound predicate, comparison predicate.
+ */
+public abstract class UnaryOperator extends Expression implements UnaryExpression, ExpectsInputTypes {
+
+    protected final String symbol;
+
+    public UnaryOperator(Expression child, String symbol) {
+        super(child);
+        this.symbol = symbol;
+    }
+
+    public abstract AbstractDataType inputType();
+
+    @Override
+    public List<AbstractDataType> expectedInputTypes() {
+        return ImmutableList.of(inputType());
+    }
+
+    @Override
+    public String toSql() {
+        return "(" + symbol + " " + child().toSql() + ")";
+    }
+
+    @Override
+    public String toString() {
+        return "(" + symbol + " " + child().toString() + ")";
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(symbol, child());
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) {
+            return true;
+        }
+        if (o == null || getClass() != o.getClass()) {
+            return false;
+        }
+        UnaryOperator other = (UnaryOperator) o;
+        return Objects.equals(child(), other.child());
+    }
+}
diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/visitor/ExpressionVisitor.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/visitor/ExpressionVisitor.java
index f905b2a5bf..62e990c498 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/visitor/ExpressionVisitor.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/visitor/ExpressionVisitor.java
@@ -28,6 +28,10 @@ import org.apache.doris.nereids.trees.expressions.AssertNumRowsElement;
 import org.apache.doris.nereids.trees.expressions.Between;
 import org.apache.doris.nereids.trees.expressions.BinaryArithmetic;
 import org.apache.doris.nereids.trees.expressions.BinaryOperator;
+import org.apache.doris.nereids.trees.expressions.BitAnd;
+import org.apache.doris.nereids.trees.expressions.BitNot;
+import org.apache.doris.nereids.trees.expressions.BitOr;
+import org.apache.doris.nereids.trees.expressions.BitXor;
 import org.apache.doris.nereids.trees.expressions.CaseWhen;
 import org.apache.doris.nereids.trees.expressions.Cast;
 import org.apache.doris.nereids.trees.expressions.ComparisonPredicate;
@@ -59,6 +63,8 @@ import org.apache.doris.nereids.trees.expressions.StringRegexPredicate;
 import org.apache.doris.nereids.trees.expressions.SubqueryExpr;
 import org.apache.doris.nereids.trees.expressions.Subtract;
 import org.apache.doris.nereids.trees.expressions.TimestampArithmetic;
+import org.apache.doris.nereids.trees.expressions.UnaryArithmetic;
+import org.apache.doris.nereids.trees.expressions.UnaryOperator;
 import org.apache.doris.nereids.trees.expressions.VirtualSlotReference;
 import org.apache.doris.nereids.trees.expressions.WhenClause;
 import org.apache.doris.nereids.trees.expressions.functions.BoundFunction;
@@ -118,6 +124,10 @@ public abstract class ExpressionVisitor<R, C>
         return visit(binaryOperator, context);
     }
 
+    public R visitUinaryOperator(UnaryOperator unaryOperator, C context) {
+        return visit(unaryOperator, context);
+    }
+
     public R visitComparisonPredicate(ComparisonPredicate cp, C context) {
         return visitBinaryOperator(cp, context);
     }
@@ -258,6 +268,10 @@ public abstract class ExpressionVisitor<R, C>
         return visit(cast, context);
     }
 
+    public R visitUnaryArithmetic(UnaryArithmetic unaryArithmetic, C context) {
+        return visitUinaryOperator(unaryArithmetic, context);
+    }
+
     public R visitBinaryArithmetic(BinaryArithmetic binaryArithmetic, C context) {
         return visitBinaryOperator(binaryArithmetic, context);
     }
@@ -278,6 +292,22 @@ public abstract class ExpressionVisitor<R, C>
         return visitBinaryArithmetic(divide, context);
     }
 
+    public R visitBitXor(BitXor bitXor, C context) {
+        return visitBinaryArithmetic(bitXor, context);
+    }
+
+    public R visitBitOr(BitOr bitOr, C context) {
+        return visitBinaryArithmetic(bitOr, context);
+    }
+
+    public R visitBitAnd(BitAnd bitAnd, C context) {
+        return visitBinaryArithmetic(bitAnd, context);
+    }
+
+    public R visitBitNot(BitNot bitNot, C context) {
+        return visitUnaryArithmetic(bitNot, context);
+    }
+
     public R visitMod(Mod mod, C context) {
         return visitBinaryArithmetic(mod, context);
     }
diff --git a/fe/fe-core/src/test/java/org/apache/doris/nereids/glue/translator/ExpressionTranslatorTest.java b/fe/fe-core/src/test/java/org/apache/doris/nereids/glue/translator/ExpressionTranslatorTest.java
new file mode 100644
index 0000000000..f40e9d196b
--- /dev/null
+++ b/fe/fe-core/src/test/java/org/apache/doris/nereids/glue/translator/ExpressionTranslatorTest.java
@@ -0,0 +1,39 @@
+// 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.glue.translator;
+
+import org.apache.doris.analysis.ArithmeticExpr;
+import org.apache.doris.analysis.ArithmeticExpr.Operator;
+import org.apache.doris.analysis.Expr;
+import org.apache.doris.analysis.IntLiteral;
+import org.apache.doris.nereids.trees.expressions.BitNot;
+import org.apache.doris.nereids.trees.expressions.literal.IntegerLiteral;
+
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+
+public class ExpressionTranslatorTest {
+
+    @Test
+    public void testUnaryArithmetic() {
+        BitNot bitNot = new BitNot(new IntegerLiteral(1));
+        ExpressionTranslator translator = ExpressionTranslator.INSTANCE;
+        Expr expr = translator.visitUnaryArithmetic(bitNot, null);
+        Assertions.assertEquals(expr, new ArithmeticExpr(Operator.BITNOT, new IntLiteral(1), null));
+    }
+}
diff --git a/regression-test/data/nereids_syntax_p0/unary_binary_arithmetic.out b/regression-test/data/nereids_syntax_p0/unary_binary_arithmetic.out
new file mode 100644
index 0000000000..f403badf7b
--- /dev/null
+++ b/regression-test/data/nereids_syntax_p0/unary_binary_arithmetic.out
@@ -0,0 +1,52 @@
+-- This file is automatically generated. You should know what you did if you want to edit this
+-- !select --
+4.0
+
+-- !select --
+\N
+
+-- !select --
+1
+
+-- !select --
+0
+
+-- !select --
+0
+
+-- !select --
+15
+
+-- !select --
+7
+
+-- !select --
+7
+
+-- !select --
+0
+
+-- !select --
+1
+
+-- !select --
+-1
+
+-- !select --
+-5
+
+-- !select --
+2
+
+-- !select --
+-8
+
+-- !select --
+-9
+
+-- !select --
+\N
+
+-- !select --
+-20000102
+
diff --git a/regression-test/suites/nereids_syntax_p0/unary_binary_arithmetic.groovy b/regression-test/suites/nereids_syntax_p0/unary_binary_arithmetic.groovy
new file mode 100644
index 0000000000..191165097d
--- /dev/null
+++ b/regression-test/suites/nereids_syntax_p0/unary_binary_arithmetic.groovy
@@ -0,0 +1,48 @@
+// 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.
+
+suite("unary_binary_arithmetic") {
+    sql "set enable_nereids_planner=true"
+    sql "set enable_fallback_to_original_planner=false"
+
+    qt_select "select 8 div 2";
+
+    qt_select "select 8 div 0";
+
+    qt_select "select 7 & 1";
+    qt_select "select 4 & 1";
+    
+    qt_select "select 7 ^ 7"
+    qt_select "select 7 ^ 8"
+
+    qt_select "select 3 | 4"
+    qt_select "select 7 | 0"
+
+    qt_select "select 4 % 2"
+    qt_select "select 99 % 2"
+
+    qt_select "select -1"
+    qt_select "select -(2+3)"
+    qt_select "select +(1+1)"
+    qt_select "select ~7"
+    qt_select "select ~8"
+    
+    qt_select "select ~'a';"
+    qt_select "select ~cast('2000-01-01' as date)"
+
+
+}


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