[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:
@ -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';
|
||||
|
||||
@ -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
|
||||
;
|
||||
;
|
||||
@ -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"),
|
||||
|
||||
@ -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, () -> {
|
||||
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
@ -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);
|
||||
}
|
||||
|
||||
@ -1101,3 +1101,9 @@ varchar13
|
||||
0.4535961214255773
|
||||
0.3623577544766736
|
||||
|
||||
-- !char --
|
||||
Doris Doris
|
||||
|
||||
-- !convert --
|
||||
1 1
|
||||
|
||||
|
||||
@ -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);"
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user