[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 root@127.0.0.1:(none)> select convert(1 using gbk);
+-------------------+
| convert(1, 'gbk') |
+-------------------+
| 1                 |
+-------------------+
```
This commit is contained in:
谢健
2023-08-30 17:09:06 +08:00
committed by GitHub
parent 509d865760
commit a136836770
8 changed files with 133 additions and 3 deletions

View File

@ -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';

View File

@ -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
;
;

View File

@ -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"),

View File

@ -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, () -> {

View File

@ -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;
}
}

View File

@ -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);
}

View File

@ -1101,3 +1101,9 @@ varchar13
0.4535961214255773
0.3623577544766736
-- !char --
Doris Doris
-- !convert --
1 1

View File

@ -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);"
}