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 a136836770 [feature](Nereids) add two functions: char and covert 
(#23104)
a136836770 is described below

commit a1368367708796fbb09e1142e9f144d1407654df
Author: 谢健 <[email protected]>
AuthorDate: Wed Aug 30 17:09:06 2023 +0800

    [feature](Nereids) add two functions: char and covert (#23104)
    
    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  |  2 +
 .../antlr4/org/apache/doris/nereids/DorisParser.g4 | 18 +++++-
 .../doris/catalog/BuiltinScalarFunctions.java      |  2 +
 .../doris/nereids/parser/LogicalPlanBuilder.java   | 34 +++++++++++
 .../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, 133 insertions(+), 3 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 35fe7f26a2..b6f1ae30e5 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
@@ -123,6 +123,7 @@ CAST: 'CAST';
 CATALOG: 'CATALOG';
 CATALOGS: 'CATALOGS';
 CHANGE: 'CHANGE';
+CHAR: 'CHAR';
 CHECK: 'CHECK';
 CLEAR: 'CLEAR';
 CLUSTER: 'CLUSTER';
@@ -139,6 +140,7 @@ COMPACTIONS: 'COMPACTIONS';
 COMPUTE: 'COMPUTE';
 CONCATENATE: 'CONCATENATE';
 CONSTRAINT: 'CONSTRAINT';
+CONVERT: 'CONVERT';
 COST: 'COST';
 CREATE: 'CREATE';
 CROSS: 'CROSS';
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 891c3a01b8..7dc1554ce1 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
@@ -404,8 +404,18 @@ primaryExpression
     | interval                                                                 
                #intervalLiteral
     | ASTERISK                                                                 
                #star
     | qualifiedName DOT ASTERISK                                               
                #star
-    | functionIdentifier LEFT_PAREN ((DISTINCT|ALL)? arguments+=expression
-      (COMMA arguments+=expression)* (ORDER BY sortItem (COMMA sortItem)*)?)? 
RIGHT_PAREN
+    | 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
     | value=primaryExpression LEFT_BRACKET index=valueExpression RIGHT_BRACKET 
                #elementAt
     | value=primaryExpression LEFT_BRACKET begin=valueExpression
@@ -584,6 +594,7 @@ nonReserved
     | CATALOG
     | CATALOGS
     | CHANGE
+    | CHAR
     | CHECK
     | CLEAR
     | CLUSTER
@@ -600,6 +611,7 @@ nonReserved
     | COMPUTE
     | CONCATENATE
     | CONSTRAINT
+    | CONVERT
     | COST
     | CREATE
     | CUBE
@@ -835,4 +847,4 @@ nonReserved
     | HDFS
     | BROKER
 //--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 8267b4f952..3dd3044404 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
@@ -82,6 +82,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;
@@ -428,6 +429,7 @@ public class BuiltinScalarFunctions implements 
FunctionHelper {
             scalar(Cardinality.class, "array_size", "cardinality", "size"),
             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 c7e7a19361..a0c6c09925 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
@@ -194,6 +194,8 @@ 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.Array;
 import org.apache.doris.nereids.trees.expressions.functions.scalar.ArraySlice;
+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.CreateMap;
 import 
org.apache.doris.nereids.trees.expressions.functions.scalar.CreateStruct;
 import org.apache.doris.nereids.trees.expressions.functions.scalar.DaysAdd;
@@ -1185,6 +1187,38 @@ public class LogicalPlanBuilder extends 
DorisParserBaseVisitor<Object> {
         return new EncryptKeyRef(new StringLiteral(db), new 
StringLiteral(key));
     }
 
+    @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) {
+        DataType dataType = ((DataType) typedVisit(ctx.type)).conversion();
+        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 0000000000..77b311835f
--- /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 0f37d870b9..a303a17736 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
@@ -86,6 +86,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;
@@ -633,6 +634,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 7f60e9d43f..17aae49730 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 47ff0b9b5d..df896d9f29 100644
--- a/regression-test/suites/nereids_function_p0/scalar_function/C.groovy
+++ b/regression-test/suites/nereids_function_p0/scalar_function/C.groovy
@@ -99,4 +99,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