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

morrysnow pushed a commit to branch branch-2.0
in repository https://gitbox.apache.org/repos/asf/doris.git


The following commit(s) were added to refs/heads/branch-2.0 by this push:
     new 6b90c988887 [feature](Nereids) add two functions: char and covert 
(#23104) (#31724)
6b90c988887 is described below

commit 6b90c98888725d9e5ba1f59a0b738f26f49a749e
Author: 谢健 <[email protected]>
AuthorDate: Tue Mar 5 11:45:02 2024 +0800

    [feature](Nereids) add two functions: char and covert (#23104) (#31724)
    
    add 
[char](https://doris.apache.org/zh-CN/docs/dev/sql-manual/sql-functions/string-functions/char/?_highlight=char)
 func
    ```
    mysql> select char(68, 111, 114, 105, 115);
    +--------------------------------------+
    | char('utf8', 68, 111, 114, 105, 115) |
    +--------------------------------------+
    | Doris                                |
    +--------------------------------------+
    ```
    
    convert func
    ```
    MySQL [email protected]:(none)> select convert(1 using gbk);
    +-------------------+
    | convert(1, 'gbk') |
    +-------------------+
    | 1                 |
    +-------------------+
    ```
---
 .../antlr4/org/apache/doris/nereids/DorisLexer.g4  |  6 ++
 .../antlr4/org/apache/doris/nereids/DorisParser.g4 | 18 +++++-
 .../doris/catalog/BuiltinScalarFunctions.java      |  2 +
 .../doris/nereids/parser/LogicalPlanBuilder.java   | 35 ++++++++++++
 .../trees/expressions/functions/scalar/Char.java   | 65 ++++++++++++++++++++++
 .../expressions/visitor/ScalarFunctionVisitor.java |  5 ++
 .../data/nereids_function_p0/scalar_function/C.out |  6 ++
 .../nereids_function_p0/scalar_function/C.groovy   |  4 ++
 8 files changed, 140 insertions(+), 1 deletion(-)

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 ddffbad133d..2a94009fc14 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
@@ -145,6 +145,7 @@ CATALOGS: 'CATALOGS';
 CHAIN: 'CHAIN';
 CHAR: 'CHAR' | 'CHARACTER';
 CHARSET: 'CHARSET';
+CHANGE: 'CHANGE';
 CHECK: 'CHECK';
 CLEAN: 'CLEAN';
 CLUSTER: 'CLUSTER';
@@ -165,6 +166,11 @@ CONSISTENT: 'CONSISTENT';
 CONVERT: 'CONVERT';
 COPY: 'COPY';
 COUNT: 'COUNT';
+COMPACTIONS: 'COMPACTIONS';
+COMPUTE: 'COMPUTE';
+CONCATENATE: 'CONCATENATE';
+CONSTRAINT: 'CONSTRAINT';
+COST: 'COST';
 CREATE: 'CREATE';
 CREATION: 'CREATION';
 CRON: 'CRON';
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 8356bfd506c..fd35ed7fd81 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
@@ -371,6 +371,12 @@ primaryExpression
     | constant                                                                 
                #constantDefault
     | ASTERISK                                                                 
                #star
     | qualifiedName DOT ASTERISK                                               
                #star
+    | CHAR LEFT_PAREN
+                    arguments+=expression (COMMA arguments+=expression)*
+                    (USING charSet=identifierOrText)?
+              RIGHT_PAREN                                                      
               #charFunction
+    | CONVERT LEFT_PAREN argument=expression USING charSet=identifierOrText 
RIGHT_PAREN       #convertCharSet
+    | CONVERT LEFT_PAREN argument=expression COMMA type=dataType RIGHT_PAREN   
               #convertType
     | functionIdentifier LEFT_PAREN ((DISTINCT|ALL)? arguments+=expression
       (COMMA arguments+=expression)* (ORDER BY sortItem (COMMA sortItem)*)?)? 
RIGHT_PAREN
       (OVER windowSpec)?                                                       
                 #functionCall
@@ -587,6 +593,7 @@ nonReserved
     | CHAIN
     | CHAR
     | CHARSET
+    | CHANGE
     | CHECK
     | CLUSTER
     | CLUSTERS
@@ -607,6 +614,15 @@ nonReserved
     | CREATION
     | CRON
     | CURRENT_CATALOG
+    | COMPACTIONS
+    | COMPUTE
+    | CONCATENATE
+    | CONSTRAINT
+    | CONVERT
+    | COST
+    | CREATE
+    | CUBE
+    | CURRENT
     | CURRENT_TIMESTAMP
     | DATA
     | DATE
@@ -826,4 +842,4 @@ nonReserved
     | WORK
     | YEAR
 //--DEFAULT-NON-RESERVED-END
-    ;
+    ;
\ No newline at end of file
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/catalog/BuiltinScalarFunctions.java 
b/fe/fe-core/src/main/java/org/apache/doris/catalog/BuiltinScalarFunctions.java
index 174b35df437..b4578b0abe9 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/catalog/BuiltinScalarFunctions.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/catalog/BuiltinScalarFunctions.java
@@ -64,6 +64,7 @@ import 
org.apache.doris.nereids.trees.expressions.functions.scalar.BitmapXorCoun
 import org.apache.doris.nereids.trees.expressions.functions.scalar.Cardinality;
 import org.apache.doris.nereids.trees.expressions.functions.scalar.Cbrt;
 import org.apache.doris.nereids.trees.expressions.functions.scalar.Ceil;
+import org.apache.doris.nereids.trees.expressions.functions.scalar.Char;
 import 
org.apache.doris.nereids.trees.expressions.functions.scalar.CharacterLength;
 import org.apache.doris.nereids.trees.expressions.functions.scalar.Coalesce;
 import org.apache.doris.nereids.trees.expressions.functions.scalar.Concat;
@@ -406,6 +407,7 @@ public class BuiltinScalarFunctions implements 
FunctionHelper {
             scalar(Cardinality.class, "cardinality"),
             scalar(Cbrt.class, "cbrt"),
             scalar(Ceil.class, "ceil", "ceiling"),
+            scalar(Char.class, "char"),
             scalar(CharacterLength.class, "char_length", "character_length"),
             scalar(Coalesce.class, "coalesce"),
             scalar(Concat.class, "concat"),
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 40427e038a0..873d7f28c19 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
@@ -183,6 +183,8 @@ import 
org.apache.doris.nereids.trees.expressions.WindowFrame;
 import org.apache.doris.nereids.trees.expressions.functions.Function;
 import org.apache.doris.nereids.trees.expressions.functions.agg.Count;
 import org.apache.doris.nereids.trees.expressions.functions.agg.GroupConcat;
+import org.apache.doris.nereids.trees.expressions.functions.scalar.Char;
+import org.apache.doris.nereids.trees.expressions.functions.scalar.ConvertTo;
 import org.apache.doris.nereids.trees.expressions.functions.scalar.DaysAdd;
 import org.apache.doris.nereids.trees.expressions.functions.scalar.DaysDiff;
 import org.apache.doris.nereids.trees.expressions.functions.scalar.DaysSub;
@@ -1164,6 +1166,39 @@ public class LogicalPlanBuilder extends 
DorisParserBaseVisitor<Object> {
         });
     }
 
+    @Override
+    public Expression visitCharFunction(DorisParser.CharFunctionContext ctx) {
+        String charSet = ctx.charSet == null ? "utf8" : ctx.charSet.getText();
+        List<Expression> arguments = ImmutableList.<Expression>builder()
+                .add(new StringLiteral(charSet))
+                .addAll(visit(ctx.arguments, Expression.class))
+                .build();
+        return new Char(arguments);
+    }
+
+    @Override
+    public Expression visitConvertCharSet(DorisParser.ConvertCharSetContext 
ctx) {
+        return new ConvertTo(getExpression(ctx.argument), new 
StringLiteral(ctx.charSet.getText()));
+    }
+
+    @Override
+    public Expression visitConvertType(DorisParser.ConvertTypeContext ctx) {
+        List<String> types = typedVisit(ctx.dataType());
+        DataType dataType = DataType.convertPrimitiveFromStrings(types, true);
+        Expression cast = ParserUtils.withOrigin(ctx, () ->
+                new Cast(getExpression(ctx.argument), dataType));
+        if (dataType.isStringLikeType() && ((CharacterType) dataType).getLen() 
>= 0) {
+            List<Expression> args = ImmutableList.of(
+                    cast,
+                    new TinyIntLiteral((byte) 1),
+                    Literal.of(((CharacterType) dataType).getLen())
+            );
+            return new UnboundFunction("substr", args);
+        } else {
+            return cast;
+        }
+    }
+
     @Override
     public Expression visitFunctionCall(DorisParser.FunctionCallContext ctx) {
         return ParserUtils.withOrigin(ctx, () -> {
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/Char.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/Char.java
new file mode 100644
index 00000000000..77b311835f6
--- /dev/null
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/Char.java
@@ -0,0 +1,65 @@
+// 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.functions.scalar;
+
+import org.apache.doris.catalog.FunctionSignature;
+import org.apache.doris.nereids.trees.expressions.Expression;
+import org.apache.doris.nereids.trees.expressions.functions.AlwaysNullable;
+import 
org.apache.doris.nereids.trees.expressions.functions.ExplicitlyCastableSignature;
+import org.apache.doris.nereids.trees.expressions.visitor.ExpressionVisitor;
+import org.apache.doris.nereids.types.IntegerType;
+import org.apache.doris.nereids.types.StringType;
+
+import com.google.common.collect.ImmutableList;
+
+import java.util.List;
+
+/**
+ * ScalarFunction 'char'.
+ */
+public class Char extends ScalarFunction
+        implements ExplicitlyCastableSignature, AlwaysNullable {
+    public static final List<FunctionSignature> SIGNATURES = ImmutableList.of(
+            
FunctionSignature.ret(StringType.INSTANCE).varArgs(StringType.INSTANCE, 
IntegerType.INSTANCE));
+
+    public Char(List<Expression> varArgs) {
+        super("char", varArgs);
+    }
+
+    public Char(Expression... varArgs) {
+        super("char", varArgs);
+    }
+
+    /**
+     * withChildren.
+     */
+    @Override
+    public Char withChildren(List<Expression> children) {
+        return new Char(children);
+    }
+
+    @Override
+    public <R, C> R accept(ExpressionVisitor<R, C> visitor, C context) {
+        return visitor.visitChar(this, context);
+    }
+
+    @Override
+    public List<FunctionSignature> getSignatures() {
+        return SIGNATURES;
+    }
+}
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/visitor/ScalarFunctionVisitor.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/visitor/ScalarFunctionVisitor.java
index 8b8b6ce21f4..8f9e6cb767d 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/visitor/ScalarFunctionVisitor.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/visitor/ScalarFunctionVisitor.java
@@ -66,6 +66,7 @@ import 
org.apache.doris.nereids.trees.expressions.functions.scalar.BitmapXorCoun
 import org.apache.doris.nereids.trees.expressions.functions.scalar.Cardinality;
 import org.apache.doris.nereids.trees.expressions.functions.scalar.Cbrt;
 import org.apache.doris.nereids.trees.expressions.functions.scalar.Ceil;
+import org.apache.doris.nereids.trees.expressions.functions.scalar.Char;
 import 
org.apache.doris.nereids.trees.expressions.functions.scalar.CharacterLength;
 import org.apache.doris.nereids.trees.expressions.functions.scalar.Coalesce;
 import org.apache.doris.nereids.trees.expressions.functions.scalar.Concat;
@@ -540,6 +541,10 @@ public interface ScalarFunctionVisitor<R, C> {
         return visitScalarFunction(concat, context);
     }
 
+    default R visitChar(Char charFunc, C context) {
+        return visitScalarFunction(charFunc, context);
+    }
+
     default R visitConcatWs(ConcatWs concatWs, C context) {
         return visitScalarFunction(concatWs, context);
     }
diff --git a/regression-test/data/nereids_function_p0/scalar_function/C.out 
b/regression-test/data/nereids_function_p0/scalar_function/C.out
index 0afb6400c74..42a41c21b0b 100644
--- a/regression-test/data/nereids_function_p0/scalar_function/C.out
+++ b/regression-test/data/nereids_function_p0/scalar_function/C.out
@@ -1101,3 +1101,9 @@ varchar13
 0.4535961214255773
 0.3623577544766736
 
+-- !char --
+Doris  Doris
+
+-- !convert --
+1      1
+
diff --git 
a/regression-test/suites/nereids_function_p0/scalar_function/C.groovy 
b/regression-test/suites/nereids_function_p0/scalar_function/C.groovy
index e6b124e9a3b..a93c5c673d7 100644
--- a/regression-test/suites/nereids_function_p0/scalar_function/C.groovy
+++ b/regression-test/suites/nereids_function_p0/scalar_function/C.groovy
@@ -93,4 +93,8 @@ suite("nereids_scalar_fn_C") {
        qt_sql_cos_Double_notnull "select cos(kdbl) from fn_test_not_nullable 
order by kdbl"
        sql "select current_user() from fn_test"
        sql "select current_user() from fn_test_not_nullable"
+
+       qt_char "select char(68, 111, 114, 105, 115), char(68, 111, 114, 105, 
115 using utf8);"
+       qt_convert "select convert(1 using gbk), convert(1, string);"
+
 }


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to