From 2c6d2255c3d8d7872ef1cea941302e0cc4719bbb Mon Sep 17 00:00:00 2001 From: morrySnow <101034200+morrySnow@users.noreply.github.com> Date: Wed, 15 Nov 2023 11:13:26 +0800 Subject: [PATCH] [fix](Nereids) nested type literal type coercion and insert values with map (#26669) --- .../nereids/rules/analysis/BindSink.java | 13 - .../expressions/ExpressionEvaluator.java | 32 +- .../functions/ComputeSignatureHelper.java | 141 ++++-- .../expressions/functions/scalar/Array.java | 21 +- .../expressions/functions/scalar/If.java | 16 +- .../doris/nereids/util/TypeCoercionUtils.java | 64 ++- .../functions/ComputeSignatureHelperTest.java | 447 ++++++++++++++++++ .../javaudf_p0/test_javaudf_all_types.out | 12 +- .../scalar_function/Array.out | 4 +- .../aggregate/map_agg_nested_insert_doris.out | 28 +- .../test_array_with_scale_type.out | 8 +- .../javaudf_p0/test_javaudf_all_types.groovy | 4 +- .../map_agg_nested_insert_doris.groovy | 20 +- 13 files changed, 669 insertions(+), 141 deletions(-) create mode 100644 fe/fe-core/src/test/java/org/apache/doris/nereids/trees/expressions/functions/ComputeSignatureHelperTest.java diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/analysis/BindSink.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/analysis/BindSink.java index 6aee5ddb9bd8c5..f3c27f6c9b2d45 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/analysis/BindSink.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/analysis/BindSink.java @@ -52,7 +52,6 @@ import org.apache.doris.nereids.types.coercion.CharacterType; import org.apache.doris.nereids.util.RelationUtil; import org.apache.doris.nereids.util.TypeCoercionUtils; -import org.apache.doris.qe.ConnectContext; import com.google.common.base.Preconditions; import com.google.common.collect.ImmutableList; @@ -226,7 +225,6 @@ public List buildRules() { // we skip it. continue; } - maybeFallbackCastUnsupportedType(expr, ctx.connectContext); DataType inputType = expr.getDataType(); DataType targetType = DataType.fromCatalogType(table.getFullSchema().get(i).getType()); Expression castExpr = expr; @@ -309,17 +307,6 @@ private List bindTargetColumns(OlapTable table, List colsName, b }).collect(ImmutableList.toImmutableList()); } - private void maybeFallbackCastUnsupportedType(Expression expression, ConnectContext ctx) { - if (expression.getDataType().isMapType()) { - try { - ctx.getSessionVariable().enableFallbackToOriginalPlannerOnce(); - } catch (Exception e) { - throw new AnalysisException("failed to try to fall back to original planner"); - } - throw new AnalysisException("failed to cast type when binding sink, type is: " + expression.getDataType()); - } - } - private boolean isSourceAndTargetStringLikeType(DataType input, DataType target) { return input.isStringLikeType() && target.isStringLikeType(); } diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/ExpressionEvaluator.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/ExpressionEvaluator.java index f17489d8a6ac24..adced61c7b7508 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/ExpressionEvaluator.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/ExpressionEvaluator.java @@ -31,11 +31,8 @@ import org.apache.doris.nereids.trees.expressions.literal.DateLiteral; import org.apache.doris.nereids.trees.expressions.literal.Literal; import org.apache.doris.nereids.trees.expressions.literal.NullLiteral; -import org.apache.doris.nereids.types.ArrayType; import org.apache.doris.nereids.types.DataType; -import org.apache.doris.nereids.types.DecimalV3Type; -import org.apache.doris.nereids.types.MapType; -import org.apache.doris.nereids.types.StructType; +import org.apache.doris.nereids.util.TypeCoercionUtils; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMultimap; @@ -167,7 +164,7 @@ private void registerFEFunction(ImmutableMultimap.Builder argTypes = new ArrayList<>(); for (String type : annotation.argTypes()) { - argTypes.add(replaceDecimalV3WithWildcard(DataType.convertFromString(type))); + argTypes.add(TypeCoercionUtils.replaceDecimalV3WithWildcard(DataType.convertFromString(type))); } FunctionSignature signature = new FunctionSignature(name, argTypes.toArray(new DataType[0]), returnType); @@ -175,31 +172,6 @@ private void registerFEFunction(ImmutableMultimap.Builder arguments) { - if (signature.returnType instanceof FollowToArgumentType) { - int argumentIndex = ((FollowToArgumentType) signature.returnType).argumentIndex; - return signature.withReturnType(arguments.get(argumentIndex).getDataType()); + return signature.withReturnType(replaceFollowToArgumentReturnType( + signature.returnType, signature.argumentsTypes)); + } + + private static DataType replaceFollowToArgumentReturnType(DataType returnType, List argumentTypes) { + if (returnType instanceof ArrayType) { + return ArrayType.of(replaceFollowToArgumentReturnType( + ((ArrayType) returnType).getItemType(), argumentTypes)); + } else if (returnType instanceof MapType) { + return MapType.of(replaceFollowToArgumentReturnType(((MapType) returnType).getKeyType(), argumentTypes), + replaceFollowToArgumentReturnType(((MapType) returnType).getValueType(), argumentTypes)); + } else if (returnType instanceof StructType) { + // TODO: do not support struct type now + // throw new AnalysisException("do not support struct type now"); + return returnType; + } else if (returnType instanceof FollowToArgumentType) { + int argumentIndex = ((FollowToArgumentType) returnType).argumentIndex; + return argumentTypes.get(argumentIndex); + } else { + return returnType; } - return signature; } private static DataType replaceAnyDataTypeWithOutIndex(DataType sigType, DataType expressionType) { @@ -308,10 +324,10 @@ public static FunctionSignature computePrecision( if (computeSignature instanceof ComputePrecision) { return ((ComputePrecision) computeSignature).computePrecision(signature); } - if (signature.argumentsTypes.stream().anyMatch(DateTimeV2Type.class::isInstance)) { + if (signature.argumentsTypes.stream().anyMatch(TypeCoercionUtils::hasDateTimeV2Type)) { signature = defaultDateTimeV2PrecisionPromotion(signature, arguments); } - if (signature.argumentsTypes.stream().anyMatch(DecimalV3Type.class::isInstance)) { + if (signature.argumentsTypes.stream().anyMatch(TypeCoercionUtils::hasDecimalV3Type)) { // do decimal v3 precision signature = defaultDecimalV3PrecisionPromotion(signature, arguments); } @@ -354,30 +370,34 @@ private static FunctionSignature defaultDateTimeV2PrecisionPromotion( } else { targetType = signature.getArgType(i); } - if (!(targetType instanceof DateTimeV2Type)) { + List argTypes = extractArgumentType(DateTimeV2Type.class, + targetType, arguments.get(i).getDataType()); + if (argTypes.isEmpty()) { continue; } - if (finalType == null) { - if (arguments.get(i) instanceof StringLikeLiteral) { - // We need to determine the scale based on the string literal. + + for (DataType argType : argTypes) { + Expression arg = arguments.get(i); + DateTimeV2Type dateTimeV2Type; + if (arg instanceof StringLikeLiteral) { StringLikeLiteral str = (StringLikeLiteral) arguments.get(i); - finalType = DateTimeV2Type.forTypeFromString(str.getStringValue()); + dateTimeV2Type = DateTimeV2Type.forTypeFromString(str.getStringValue()); } else { - finalType = DateTimeV2Type.forType(arguments.get(i).getDataType()); + dateTimeV2Type = DateTimeV2Type.forType(argType); + } + if (finalType == null) { + finalType = dateTimeV2Type; + } else { + finalType = DateTimeV2Type.getWiderDatetimeV2Type(finalType, + DateTimeV2Type.forType(arguments.get(i).getDataType())); } - } else { - finalType = DateTimeV2Type.getWiderDatetimeV2Type(finalType, - DateTimeV2Type.forType(arguments.get(i).getDataType())); } } DateTimeV2Type argType = finalType; - List newArgTypes = signature.argumentsTypes.stream().map(t -> { - if (t instanceof DateTimeV2Type) { - return argType; - } else { - return t; - } - }).collect(Collectors.toList()); + List newArgTypes = signature.argumentsTypes.stream() + .map(at -> TypeCoercionUtils.replaceDateTimeV2WithTarget(at, argType)) + .collect(Collectors.toList()); + signature = signature.withArgumentTypes(signature.hasVarArgs, newArgTypes); signature = signature.withArgumentTypes(signature.hasVarArgs, newArgTypes); if (signature.returnType instanceof DateTimeV2Type) { signature = signature.withReturnType(argType); @@ -387,7 +407,7 @@ private static FunctionSignature defaultDateTimeV2PrecisionPromotion( private static FunctionSignature defaultDecimalV3PrecisionPromotion( FunctionSignature signature, List arguments) { - DataType finalType = null; + DecimalV3Type finalType = null; for (int i = 0; i < arguments.size(); i++) { DataType targetType; if (i >= signature.argumentsTypes.size()) { @@ -397,37 +417,32 @@ private static FunctionSignature defaultDecimalV3PrecisionPromotion( } else { targetType = signature.getArgType(i); } - if (!(targetType instanceof DecimalV3Type)) { - continue; - } - // only process wildcard decimalv3 - if (((DecimalV3Type) targetType).getPrecision() > 0) { + List argTypes = extractArgumentType(DecimalV3Type.class, + targetType, arguments.get(i).getDataType()); + if (argTypes.isEmpty()) { continue; } - if (finalType == null) { - finalType = DecimalV3Type.forType(arguments.get(i).getDataType()); - } else { + + for (DataType argType : argTypes) { Expression arg = arguments.get(i); - DecimalV3Type argType; + DecimalV3Type decimalV3Type; if (arg.isLiteral() && arg.getDataType().isIntegralType()) { // create decimalV3 with minimum scale enough to hold the integral literal - argType = DecimalV3Type.createDecimalV3Type(new BigDecimal(((Literal) arg).getStringValue())); + decimalV3Type = DecimalV3Type.createDecimalV3Type(new BigDecimal(((Literal) arg).getStringValue())); + } else { + decimalV3Type = DecimalV3Type.forType(argType); + } + if (finalType == null) { + finalType = decimalV3Type; } else { - argType = DecimalV3Type.forType(arg.getDataType()); + finalType = (DecimalV3Type) DecimalV3Type.widerDecimalV3Type(finalType, decimalV3Type, false); } - finalType = DecimalV3Type.widerDecimalV3Type((DecimalV3Type) finalType, argType, true); } - Preconditions.checkState(finalType.isDecimalV3Type(), "decimalv3 precision promotion failed."); } - DataType argType = finalType; - List newArgTypes = signature.argumentsTypes.stream().map(t -> { - // only process wildcard decimalv3 - if (t instanceof DecimalV3Type && ((DecimalV3Type) t).getPrecision() <= 0) { - return argType; - } else { - return t; - } - }).collect(Collectors.toList()); + DecimalV3Type argType = finalType; + List newArgTypes = signature.argumentsTypes.stream() + .map(at -> TypeCoercionUtils.replaceDecimalV3WithTarget(at, argType)) + .collect(Collectors.toList()); signature = signature.withArgumentTypes(signature.hasVarArgs, newArgTypes); if (signature.returnType instanceof DecimalV3Type && ((DecimalV3Type) signature.returnType).getPrecision() <= 0) { @@ -436,6 +451,42 @@ private static FunctionSignature defaultDecimalV3PrecisionPromotion( return signature; } + private static List extractArgumentType(Class targetType, + DataType signatureType, DataType argumentType) { + if (targetType.isAssignableFrom(signatureType.getClass())) { + return Lists.newArrayList(argumentType); + } else if (signatureType instanceof ArrayType) { + if (argumentType instanceof NullType) { + return extractArgumentType(targetType, ((ArrayType) signatureType).getItemType(), argumentType); + } else if (argumentType instanceof ArrayType) { + return extractArgumentType(targetType, + ((ArrayType) signatureType).getItemType(), ((ArrayType) argumentType).getItemType()); + } else { + return Lists.newArrayList(); + } + } else if (signatureType instanceof MapType) { + if (argumentType instanceof NullType) { + List ret = extractArgumentType(targetType, + ((MapType) signatureType).getKeyType(), argumentType); + ret.addAll(extractArgumentType(targetType, ((MapType) signatureType).getValueType(), argumentType)); + return ret; + } else if (argumentType instanceof MapType) { + List ret = extractArgumentType(targetType, + ((MapType) signatureType).getKeyType(), ((MapType) argumentType).getKeyType()); + ret.addAll(extractArgumentType(targetType, + ((MapType) signatureType).getValueType(), ((MapType) argumentType).getValueType())); + return ret; + } else { + return Lists.newArrayList(); + } + } else if (signatureType instanceof StructType) { + // TODO: do not support struct type now + return Lists.newArrayList(); + } else { + return Lists.newArrayList(); + } + } + static class ComputeSignatureChain { private final ResponsibilityChain computeChain; diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/Array.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/Array.java index ea74eaefdf5627..0b7523a2d5ca86 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/Array.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/Array.java @@ -25,6 +25,7 @@ import org.apache.doris.nereids.trees.expressions.visitor.ExpressionVisitor; import org.apache.doris.nereids.types.ArrayType; import org.apache.doris.nereids.types.DataType; +import org.apache.doris.nereids.types.coercion.FollowToArgumentType; import org.apache.doris.nereids.util.TypeCoercionUtils; import com.google.common.collect.ImmutableList; @@ -79,9 +80,27 @@ public List getSignatures() { .map(TypeCoercionUtils::replaceCharacterToString) .collect(Collectors.toList()); } + partitioned = partitioned.get(false).stream() + .collect(Collectors.partitioningBy(TypeCoercionUtils::hasDecimalV2Type)); + if (!partitioned.get(true).isEmpty()) { + needTypeCoercion.addAll(partitioned.get(true).stream() + .map(TypeCoercionUtils::replaceDecimalV2WithDefault).collect(Collectors.toList())); + } + partitioned = partitioned.get(false).stream() + .collect(Collectors.partitioningBy(TypeCoercionUtils::hasDecimalV3Type)); + if (!partitioned.get(true).isEmpty()) { + needTypeCoercion.addAll(partitioned.get(true).stream() + .map(TypeCoercionUtils::replaceDecimalV3WithWildcard).collect(Collectors.toList())); + } + partitioned = partitioned.get(false).stream() + .collect(Collectors.partitioningBy(TypeCoercionUtils::hasDateTimeV2Type)); + if (!partitioned.get(true).isEmpty()) { + needTypeCoercion.addAll(partitioned.get(true).stream() + .map(TypeCoercionUtils::replaceDateTimeV2WithMax).collect(Collectors.toList())); + } needTypeCoercion.addAll(partitioned.get(false)); return needTypeCoercion.stream() - .map(dataType -> FunctionSignature.ret(ArrayType.of(dataType)).varArgs(dataType)) + .map(dataType -> FunctionSignature.ret(ArrayType.of(new FollowToArgumentType(0))).varArgs(dataType)) .collect(ImmutableList.toImmutableList()); } } diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/If.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/If.java index 0d695515a85ee2..8f98e7641b16b7 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/If.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/If.java @@ -37,6 +37,8 @@ import org.apache.doris.nereids.types.HllType; import org.apache.doris.nereids.types.IntegerType; import org.apache.doris.nereids.types.LargeIntType; +import org.apache.doris.nereids.types.MapType; +import org.apache.doris.nereids.types.NullType; import org.apache.doris.nereids.types.SmallIntType; import org.apache.doris.nereids.types.StringType; import org.apache.doris.nereids.types.TinyIntType; @@ -55,9 +57,8 @@ public class If extends ScalarFunction implements TernaryExpression, ExplicitlyCastableSignature { public static final List SIGNATURES = ImmutableList.of( - FunctionSignature.retArgType(1) - .args(BooleanType.INSTANCE, ArrayType.of(new AnyDataType(0)), - ArrayType.of(new AnyDataType(0))), + FunctionSignature.ret(NullType.INSTANCE) + .args(BooleanType.INSTANCE, NullType.INSTANCE, NullType.INSTANCE), FunctionSignature.ret(DateTimeV2Type.SYSTEM_DEFAULT) .args(BooleanType.INSTANCE, DateTimeV2Type.SYSTEM_DEFAULT, DateTimeV2Type.SYSTEM_DEFAULT), FunctionSignature.ret(DateV2Type.INSTANCE) @@ -88,6 +89,15 @@ public class If extends ScalarFunction FunctionSignature.ret(BitmapType.INSTANCE) .args(BooleanType.INSTANCE, BitmapType.INSTANCE, BitmapType.INSTANCE), FunctionSignature.ret(HllType.INSTANCE).args(BooleanType.INSTANCE, HllType.INSTANCE, HllType.INSTANCE), + FunctionSignature.retArgType(1) + .args(BooleanType.INSTANCE, ArrayType.of(new AnyDataType(0)), + ArrayType.of(new AnyDataType(0))), + FunctionSignature.retArgType(1) + .args(BooleanType.INSTANCE, MapType.of(new AnyDataType(0), new AnyDataType(1)), + MapType.of(new AnyDataType(0), new AnyDataType(1))), + FunctionSignature.retArgType(1) + .args(BooleanType.INSTANCE, new AnyDataType(0), new AnyDataType(0)), + // NOTICE string must at least of signature list, because all complex type could implicit cast to string FunctionSignature.ret(VarcharType.SYSTEM_DEFAULT) .args(BooleanType.INSTANCE, VarcharType.SYSTEM_DEFAULT, VarcharType.SYSTEM_DEFAULT), FunctionSignature.ret(StringType.INSTANCE) diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/util/TypeCoercionUtils.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/util/TypeCoercionUtils.java index 490c97a47fc49e..2a6ba2f2ee8895 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/util/TypeCoercionUtils.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/util/TypeCoercionUtils.java @@ -274,33 +274,75 @@ private static Optional implicitCastPrimitiveInternal(DataType input, * return ture if datatype has character type in it, cannot use instance of CharacterType because of complex type. */ public static boolean hasCharacterType(DataType dataType) { + return hasSpecifiedType(dataType, CharacterType.class); + } + + public static boolean hasDecimalV2Type(DataType dataType) { + return hasSpecifiedType(dataType, DecimalV2Type.class); + } + + public static boolean hasDecimalV3Type(DataType dataType) { + return hasSpecifiedType(dataType, DecimalV3Type.class); + } + + public static boolean hasDateTimeV2Type(DataType dataType) { + return hasSpecifiedType(dataType, DateTimeV2Type.class); + } + + private static boolean hasSpecifiedType(DataType dataType, Class specifiedType) { if (dataType instanceof ArrayType) { - return hasCharacterType(((ArrayType) dataType).getItemType()); + return hasSpecifiedType(((ArrayType) dataType).getItemType(), specifiedType); } else if (dataType instanceof MapType) { - return hasCharacterType(((MapType) dataType).getKeyType()) - || hasCharacterType(((MapType) dataType).getValueType()); + return hasSpecifiedType(((MapType) dataType).getKeyType(), specifiedType) + || hasSpecifiedType(((MapType) dataType).getValueType(), specifiedType); } else if (dataType instanceof StructType) { - return ((StructType) dataType).getFields().stream().anyMatch(f -> hasCharacterType(f.getDataType())); + return ((StructType) dataType).getFields().stream() + .anyMatch(f -> hasSpecifiedType(f.getDataType(), specifiedType)); } - return dataType instanceof CharacterType; + return specifiedType.isAssignableFrom(dataType.getClass()); } /** * replace all character types to string for correct type coercion */ public static DataType replaceCharacterToString(DataType dataType) { + return replaceSpecifiedType(dataType, CharacterType.class, StringType.INSTANCE); + } + + public static DataType replaceDecimalV2WithDefault(DataType dataType) { + return replaceSpecifiedType(dataType, DecimalV2Type.class, DecimalV2Type.SYSTEM_DEFAULT); + } + + public static DataType replaceDecimalV3WithTarget(DataType dataType, DecimalV3Type target) { + return replaceSpecifiedType(dataType, DecimalV3Type.class, target); + } + + public static DataType replaceDecimalV3WithWildcard(DataType dataType) { + return replaceSpecifiedType(dataType, DecimalV3Type.class, DecimalV3Type.WILDCARD); + } + + public static DataType replaceDateTimeV2WithTarget(DataType dataType, DateTimeV2Type target) { + return replaceSpecifiedType(dataType, DateTimeV2Type.class, target); + } + + public static DataType replaceDateTimeV2WithMax(DataType dataType) { + return replaceSpecifiedType(dataType, DateTimeV2Type.class, DateTimeV2Type.MAX); + } + + private static DataType replaceSpecifiedType(DataType dataType, + Class specifiedType, DataType newType) { if (dataType instanceof ArrayType) { - return ArrayType.of(replaceCharacterToString(((ArrayType) dataType).getItemType())); + return ArrayType.of(replaceSpecifiedType(((ArrayType) dataType).getItemType(), specifiedType, newType)); } else if (dataType instanceof MapType) { - return MapType.of(replaceCharacterToString(((MapType) dataType).getKeyType()), - replaceCharacterToString(((MapType) dataType).getValueType())); + return MapType.of(replaceSpecifiedType(((MapType) dataType).getKeyType(), specifiedType, newType), + replaceSpecifiedType(((MapType) dataType).getValueType(), specifiedType, newType)); } else if (dataType instanceof StructType) { List newFields = ((StructType) dataType).getFields().stream() - .map(f -> f.withDataType(replaceCharacterToString(f.getDataType()))) + .map(f -> f.withDataType(replaceSpecifiedType(f.getDataType(), specifiedType, newType))) .collect(ImmutableList.toImmutableList()); return new StructType(newFields); - } else if (dataType instanceof CharacterType) { - return StringType.INSTANCE; + } else if (specifiedType.isAssignableFrom(dataType.getClass())) { + return newType; } else { return dataType; } diff --git a/fe/fe-core/src/test/java/org/apache/doris/nereids/trees/expressions/functions/ComputeSignatureHelperTest.java b/fe/fe-core/src/test/java/org/apache/doris/nereids/trees/expressions/functions/ComputeSignatureHelperTest.java new file mode 100644 index 00000000000000..63a26b80a4e5c9 --- /dev/null +++ b/fe/fe-core/src/test/java/org/apache/doris/nereids/trees/expressions/functions/ComputeSignatureHelperTest.java @@ -0,0 +1,447 @@ +// 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; + +import org.apache.doris.catalog.FunctionSignature; +import org.apache.doris.nereids.trees.expressions.Expression; +import org.apache.doris.nereids.trees.expressions.literal.ArrayLiteral; +import org.apache.doris.nereids.trees.expressions.literal.BigIntLiteral; +import org.apache.doris.nereids.trees.expressions.literal.DateTimeV2Literal; +import org.apache.doris.nereids.trees.expressions.literal.DecimalV3Literal; +import org.apache.doris.nereids.trees.expressions.literal.IntegerLiteral; +import org.apache.doris.nereids.trees.expressions.literal.MapLiteral; +import org.apache.doris.nereids.trees.expressions.literal.NullLiteral; +import org.apache.doris.nereids.trees.expressions.literal.SmallIntLiteral; +import org.apache.doris.nereids.types.ArrayType; +import org.apache.doris.nereids.types.BigIntType; +import org.apache.doris.nereids.types.BooleanType; +import org.apache.doris.nereids.types.DateTimeV2Type; +import org.apache.doris.nereids.types.DecimalV2Type; +import org.apache.doris.nereids.types.DecimalV3Type; +import org.apache.doris.nereids.types.DoubleType; +import org.apache.doris.nereids.types.IntegerType; +import org.apache.doris.nereids.types.MapType; +import org.apache.doris.nereids.types.NullType; +import org.apache.doris.nereids.types.SmallIntType; +import org.apache.doris.nereids.types.coercion.AnyDataType; +import org.apache.doris.nereids.types.coercion.FollowToAnyDataType; +import org.apache.doris.nereids.types.coercion.FollowToArgumentType; + +import com.google.common.collect.Lists; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +import java.math.BigDecimal; +import java.util.Collections; +import java.util.List; + +public class ComputeSignatureHelperTest { + + ///////////////////////////////////////// + // implementFollowToArgumentReturnType + ///////////////////////////////////////// + + @Test + void testNoImplementFollowToArgumentReturnType() { + FunctionSignature signature = FunctionSignature.ret(DoubleType.INSTANCE).args(IntegerType.INSTANCE); + signature = ComputeSignatureHelper.implementFollowToArgumentReturnType(signature, Collections.emptyList()); + Assertions.assertTrue(signature.returnType instanceof DoubleType); + } + + @Test + void testArrayImplementFollowToArgumentReturnType() { + FunctionSignature signature = FunctionSignature.ret(ArrayType.of(new FollowToArgumentType(0))) + .args(IntegerType.INSTANCE); + signature = ComputeSignatureHelper.implementFollowToArgumentReturnType(signature, Collections.emptyList()); + Assertions.assertTrue(signature.returnType instanceof ArrayType); + Assertions.assertTrue(((ArrayType) signature.returnType).getItemType() instanceof IntegerType); + } + + @Test + void testMapImplementFollowToArgumentReturnType() { + FunctionSignature signature = FunctionSignature.ret(MapType.of( + new FollowToArgumentType(0), new FollowToArgumentType(1))) + .args(IntegerType.INSTANCE, DoubleType.INSTANCE); + signature = ComputeSignatureHelper.implementFollowToArgumentReturnType(signature, Collections.emptyList()); + Assertions.assertTrue(signature.returnType instanceof MapType); + Assertions.assertTrue(((MapType) signature.returnType).getKeyType() instanceof IntegerType); + Assertions.assertTrue(((MapType) signature.returnType).getValueType() instanceof DoubleType); + } + + ///////////////////////////////////////// + // implementAnyDataTypeWithOutIndex + ///////////////////////////////////////// + + @Test + void testNoImplementAnyDataTypeWithOutIndex() { + FunctionSignature signature = FunctionSignature.ret(DoubleType.INSTANCE).args(IntegerType.INSTANCE); + signature = ComputeSignatureHelper.implementAnyDataTypeWithOutIndex(signature, Collections.emptyList()); + Assertions.assertTrue(signature.returnType instanceof DoubleType); + } + + @Test + void testArraySigWithNullArgImplementAnyDataTypeWithOutIndex() { + FunctionSignature signature = FunctionSignature.ret(IntegerType.INSTANCE) + .args(ArrayType.of(AnyDataType.INSTANCE_WITHOUT_INDEX)); + List arguments = Lists.newArrayList(new NullLiteral()); + signature = ComputeSignatureHelper.implementAnyDataTypeWithOutIndex(signature, arguments); + Assertions.assertTrue(signature.getArgType(0) instanceof ArrayType); + Assertions.assertTrue(((ArrayType) signature.getArgType(0)).getItemType() instanceof NullType); + } + + @Test + void testMapSigWithNullArgImplementAnyDataTypeWithOutIndex() { + FunctionSignature signature = FunctionSignature.ret(IntegerType.INSTANCE) + .args(MapType.of(AnyDataType.INSTANCE_WITHOUT_INDEX, AnyDataType.INSTANCE_WITHOUT_INDEX)); + List arguments = Lists.newArrayList(new NullLiteral()); + signature = ComputeSignatureHelper.implementAnyDataTypeWithOutIndex(signature, arguments); + Assertions.assertTrue(signature.getArgType(0) instanceof MapType); + Assertions.assertTrue(((MapType) signature.getArgType(0)).getKeyType() instanceof NullType); + Assertions.assertTrue(((MapType) signature.getArgType(0)).getValueType() instanceof NullType); + } + + @Test + void testArrayImplementAnyDataTypeWithOutIndex() { + FunctionSignature signature = FunctionSignature.ret(IntegerType.INSTANCE) + .args(ArrayType.of(AnyDataType.INSTANCE_WITHOUT_INDEX)); + List arguments = Lists.newArrayList(new ArrayLiteral(Lists.newArrayList(new IntegerLiteral(0)))); + signature = ComputeSignatureHelper.implementAnyDataTypeWithOutIndex(signature, arguments); + Assertions.assertTrue(signature.getArgType(0) instanceof ArrayType); + Assertions.assertTrue(((ArrayType) signature.getArgType(0)).getItemType() instanceof IntegerType); + } + + @Test + void testMapImplementAnyDataTypeWithOutIndex() { + FunctionSignature signature = FunctionSignature.ret(IntegerType.INSTANCE) + .args(MapType.of(AnyDataType.INSTANCE_WITHOUT_INDEX, AnyDataType.INSTANCE_WITHOUT_INDEX)); + List arguments = Lists.newArrayList(new MapLiteral(Lists.newArrayList(new IntegerLiteral(0)), + Lists.newArrayList(new BigIntLiteral(0)))); + signature = ComputeSignatureHelper.implementAnyDataTypeWithOutIndex(signature, arguments); + Assertions.assertTrue(signature.getArgType(0) instanceof MapType); + Assertions.assertTrue(((MapType) signature.getArgType(0)).getKeyType() instanceof IntegerType); + Assertions.assertTrue(((MapType) signature.getArgType(0)).getValueType() instanceof BigIntType); + } + + ///////////////////////////////////////// + // implementAnyDataTypeWithIndex + ///////////////////////////////////////// + + @Test + void testNoImplementAnyDataTypeWithIndex() { + FunctionSignature signature = FunctionSignature.ret(DoubleType.INSTANCE).args(IntegerType.INSTANCE); + signature = ComputeSignatureHelper.implementAnyDataTypeWithIndex(signature, Collections.emptyList()); + Assertions.assertTrue(signature.returnType instanceof DoubleType); + } + + @Test + void testArraySigWithNullArgImplementAnyDataTypeWithIndex() { + FunctionSignature signature = FunctionSignature.ret(IntegerType.INSTANCE) + .args(ArrayType.of(new AnyDataType(0)), new AnyDataType(0)); + List arguments = Lists.newArrayList( + new NullLiteral(), + new BigIntLiteral(0)); + signature = ComputeSignatureHelper.implementAnyDataTypeWithIndex(signature, arguments); + Assertions.assertTrue(signature.getArgType(0) instanceof ArrayType); + Assertions.assertTrue(((ArrayType) signature.getArgType(0)).getItemType() instanceof BigIntType); + Assertions.assertTrue(signature.getArgType(1) instanceof BigIntType); + } + + @Test + void testMapSigWithNullArgImplementAnyDataTypeWithIndex() { + FunctionSignature signature = FunctionSignature.ret(IntegerType.INSTANCE) + .args(MapType.of(new AnyDataType(0), new AnyDataType(1)), + new AnyDataType(0), new AnyDataType(1)); + List arguments = Lists.newArrayList( + new NullLiteral(), new BigIntLiteral(0), new IntegerLiteral(0)); + signature = ComputeSignatureHelper.implementAnyDataTypeWithIndex(signature, arguments); + Assertions.assertTrue(signature.getArgType(0) instanceof MapType); + Assertions.assertTrue(((MapType) signature.getArgType(0)).getKeyType() instanceof BigIntType); + Assertions.assertTrue(((MapType) signature.getArgType(0)).getValueType() instanceof IntegerType); + Assertions.assertTrue(signature.getArgType(1) instanceof BigIntType); + Assertions.assertTrue(signature.getArgType(2) instanceof IntegerType); + } + + @Test + void testArrayImplementAnyDataTypeWithIndex() { + FunctionSignature signature = FunctionSignature.ret(IntegerType.INSTANCE) + .args(ArrayType.of(new AnyDataType(0)), new AnyDataType(0)); + List arguments = Lists.newArrayList( + new ArrayLiteral(Lists.newArrayList(new IntegerLiteral(0))), + new BigIntLiteral(0)); + signature = ComputeSignatureHelper.implementAnyDataTypeWithIndex(signature, arguments); + Assertions.assertTrue(signature.getArgType(0) instanceof ArrayType); + Assertions.assertTrue(((ArrayType) signature.getArgType(0)).getItemType() instanceof BigIntType); + Assertions.assertTrue(signature.getArgType(1) instanceof BigIntType); + } + + @Test + void testMapImplementAnyDataTypeWithIndex() { + FunctionSignature signature = FunctionSignature.ret(IntegerType.INSTANCE) + .args(MapType.of(new AnyDataType(0), new AnyDataType(1)), + new AnyDataType(0), new AnyDataType(1)); + List arguments = Lists.newArrayList( + new MapLiteral(Lists.newArrayList(new IntegerLiteral(0)), Lists.newArrayList(new BigIntLiteral(0))), + new BigIntLiteral(0), new IntegerLiteral(0)); + signature = ComputeSignatureHelper.implementAnyDataTypeWithIndex(signature, arguments); + Assertions.assertTrue(signature.getArgType(0) instanceof MapType); + Assertions.assertTrue(((MapType) signature.getArgType(0)).getKeyType() instanceof BigIntType); + Assertions.assertTrue(((MapType) signature.getArgType(0)).getValueType() instanceof BigIntType); + Assertions.assertTrue(signature.getArgType(1) instanceof BigIntType); + Assertions.assertTrue(signature.getArgType(2) instanceof BigIntType); + } + + @Test + void testArraySigWithNullArgWithFollowToAnyImplementAnyDataTypeWithIndex() { + FunctionSignature signature = FunctionSignature.ret(IntegerType.INSTANCE) + .args(ArrayType.of(new AnyDataType(0)), new AnyDataType(0), + ArrayType.of(new FollowToAnyDataType(0))); + List arguments = Lists.newArrayList( + new NullLiteral(), + new NullLiteral(), + new ArrayLiteral(Lists.newArrayList(new SmallIntLiteral((byte) 0)))); + signature = ComputeSignatureHelper.implementAnyDataTypeWithIndex(signature, arguments); + Assertions.assertTrue(signature.getArgType(0) instanceof ArrayType); + Assertions.assertTrue(((ArrayType) signature.getArgType(0)).getItemType() instanceof SmallIntType); + Assertions.assertTrue(signature.getArgType(1) instanceof SmallIntType); + Assertions.assertTrue(signature.getArgType(2) instanceof ArrayType); + Assertions.assertTrue(((ArrayType) signature.getArgType(2)).getItemType() instanceof SmallIntType); + } + + @Test + void testMapSigWithNullArgWithFollowToAnyImplementAnyDataTypeWithIndex() { + FunctionSignature signature = FunctionSignature.ret(IntegerType.INSTANCE) + .args(MapType.of(new AnyDataType(0), new AnyDataType(1)), + new AnyDataType(0), new AnyDataType(1), + MapType.of(new FollowToAnyDataType(0), new FollowToAnyDataType(1))); + List arguments = Lists.newArrayList( + new NullLiteral(), new NullLiteral(), new NullLiteral(), + new MapLiteral(Lists.newArrayList(new BigIntLiteral(0)), + Lists.newArrayList(new IntegerLiteral(0)))); + signature = ComputeSignatureHelper.implementAnyDataTypeWithIndex(signature, arguments); + Assertions.assertTrue(signature.getArgType(0) instanceof MapType); + Assertions.assertTrue(((MapType) signature.getArgType(0)).getKeyType() instanceof BigIntType); + Assertions.assertTrue(((MapType) signature.getArgType(0)).getValueType() instanceof IntegerType); + Assertions.assertTrue(signature.getArgType(1) instanceof BigIntType); + Assertions.assertTrue(signature.getArgType(2) instanceof IntegerType); + Assertions.assertTrue(signature.getArgType(3) instanceof MapType); + Assertions.assertTrue(((MapType) signature.getArgType(3)).getKeyType() instanceof BigIntType); + Assertions.assertTrue(((MapType) signature.getArgType(3)).getValueType() instanceof IntegerType); + } + + @Test + void testArrayWithFollowToAnyImplementAnyDataTypeWithIndex() { + FunctionSignature signature = FunctionSignature.ret(IntegerType.INSTANCE) + .args(ArrayType.of(new AnyDataType(0)), new AnyDataType(0), + ArrayType.of(new FollowToAnyDataType(0))); + List arguments = Lists.newArrayList( + new ArrayLiteral(Lists.newArrayList(new IntegerLiteral(0))), + new BigIntLiteral(0), + new ArrayLiteral(Lists.newArrayList(new IntegerLiteral(0)))); + signature = ComputeSignatureHelper.implementAnyDataTypeWithIndex(signature, arguments); + Assertions.assertTrue(signature.getArgType(0) instanceof ArrayType); + Assertions.assertTrue(((ArrayType) signature.getArgType(0)).getItemType() instanceof BigIntType); + Assertions.assertTrue(signature.getArgType(1) instanceof BigIntType); + Assertions.assertTrue(signature.getArgType(2) instanceof ArrayType); + Assertions.assertTrue(((ArrayType) signature.getArgType(2)).getItemType() instanceof BigIntType); + } + + @Test + void testMapWithFollowToAnyImplementAnyDataTypeWithIndex() { + FunctionSignature signature = FunctionSignature.ret(IntegerType.INSTANCE) + .args(MapType.of(new AnyDataType(0), new AnyDataType(1)), + new AnyDataType(0), new AnyDataType(1), + MapType.of(new FollowToAnyDataType(0), new FollowToAnyDataType(1))); + List arguments = Lists.newArrayList( + new MapLiteral(Lists.newArrayList(new IntegerLiteral(0)), Lists.newArrayList(new BigIntLiteral(0))), + new BigIntLiteral(0), new IntegerLiteral(0), + new MapLiteral(Lists.newArrayList(new IntegerLiteral(0)), Lists.newArrayList(new BigIntLiteral(0)))); + signature = ComputeSignatureHelper.implementAnyDataTypeWithIndex(signature, arguments); + Assertions.assertTrue(signature.getArgType(0) instanceof MapType); + Assertions.assertTrue(((MapType) signature.getArgType(0)).getKeyType() instanceof BigIntType); + Assertions.assertTrue(((MapType) signature.getArgType(0)).getValueType() instanceof BigIntType); + Assertions.assertTrue(signature.getArgType(1) instanceof BigIntType); + Assertions.assertTrue(signature.getArgType(2) instanceof BigIntType); + Assertions.assertTrue(signature.getArgType(3) instanceof MapType); + Assertions.assertTrue(((MapType) signature.getArgType(3)).getKeyType() instanceof BigIntType); + Assertions.assertTrue(((MapType) signature.getArgType(3)).getValueType() instanceof BigIntType); + } + + @Test + void testNoNormalizeDecimalV2() { + FunctionSignature signature = FunctionSignature.ret(IntegerType.INSTANCE).args(); + signature = ComputeSignatureHelper.normalizeDecimalV2(signature, Collections.emptyList()); + Assertions.assertEquals(IntegerType.INSTANCE, signature.returnType); + } + + @Test + void testNormalizeDecimalV2() { + FunctionSignature signature = FunctionSignature.ret(DecimalV2Type.createDecimalV2Type(15, 3)).args(); + signature = ComputeSignatureHelper.normalizeDecimalV2(signature, Collections.emptyList()); + Assertions.assertEquals(DecimalV2Type.SYSTEM_DEFAULT, signature.returnType); + } + + @Test + void testArrayDecimalV3ComputePrecision() { + FunctionSignature signature = FunctionSignature.ret(BooleanType.INSTANCE) + .args(ArrayType.of(DecimalV3Type.WILDCARD), + ArrayType.of(DecimalV3Type.WILDCARD), + DecimalV3Type.WILDCARD, + IntegerType.INSTANCE, + ArrayType.of(IntegerType.INSTANCE)); + List arguments = Lists.newArrayList( + new ArrayLiteral(Lists.newArrayList(new DecimalV3Literal(new BigDecimal("1.1234")))), + new NullLiteral(), + new DecimalV3Literal(new BigDecimal("123.123")), + new IntegerLiteral(0), + new ArrayLiteral(Lists.newArrayList(new IntegerLiteral(0)))); + signature = ComputeSignatureHelper.computePrecision(new FakeComputeSignature(), signature, arguments); + Assertions.assertTrue(signature.getArgType(0) instanceof ArrayType); + Assertions.assertEquals(DecimalV3Type.createDecimalV3Type(7, 4), + ((ArrayType) signature.getArgType(0)).getItemType()); + Assertions.assertTrue(signature.getArgType(1) instanceof ArrayType); + Assertions.assertEquals(DecimalV3Type.createDecimalV3Type(7, 4), + ((ArrayType) signature.getArgType(1)).getItemType()); + Assertions.assertEquals(DecimalV3Type.createDecimalV3Type(7, 4), + signature.getArgType(2)); + Assertions.assertTrue(signature.getArgType(4) instanceof ArrayType); + Assertions.assertEquals(IntegerType.INSTANCE, + ((ArrayType) signature.getArgType(4)).getItemType()); + } + + @Test + void testMapDecimalV3ComputePrecision() { + FunctionSignature signature = FunctionSignature.ret(BooleanType.INSTANCE) + .args(MapType.of(DecimalV3Type.WILDCARD, DecimalV3Type.WILDCARD), + MapType.of(DecimalV3Type.WILDCARD, DecimalV3Type.WILDCARD), + DecimalV3Type.WILDCARD); + List arguments = Lists.newArrayList( + new MapLiteral(Lists.newArrayList(new DecimalV3Literal(new BigDecimal("1.1234"))), + Lists.newArrayList(new DecimalV3Literal(new BigDecimal("12.12345")))), + new NullLiteral(), + new DecimalV3Literal(new BigDecimal("123.123"))); + signature = ComputeSignatureHelper.computePrecision(new FakeComputeSignature(), signature, arguments); + Assertions.assertTrue(signature.getArgType(0) instanceof MapType); + Assertions.assertEquals(DecimalV3Type.createDecimalV3Type(8, 5), + ((MapType) signature.getArgType(0)).getKeyType()); + Assertions.assertEquals(DecimalV3Type.createDecimalV3Type(8, 5), + ((MapType) signature.getArgType(0)).getValueType()); + Assertions.assertTrue(signature.getArgType(1) instanceof MapType); + Assertions.assertEquals(DecimalV3Type.createDecimalV3Type(8, 5), + ((MapType) signature.getArgType(1)).getKeyType()); + Assertions.assertEquals(DecimalV3Type.createDecimalV3Type(8, 5), + ((MapType) signature.getArgType(1)).getValueType()); + Assertions.assertEquals(DecimalV3Type.createDecimalV3Type(8, 5), + signature.getArgType(2)); + } + + @Test + void testArrayDateTimeV2ComputePrecision() { + FunctionSignature signature = FunctionSignature.ret(BooleanType.INSTANCE) + .args(ArrayType.of(DateTimeV2Type.SYSTEM_DEFAULT), + ArrayType.of(DateTimeV2Type.SYSTEM_DEFAULT), + DateTimeV2Type.SYSTEM_DEFAULT, + IntegerType.INSTANCE, + ArrayType.of(IntegerType.INSTANCE)); + List arguments = Lists.newArrayList( + new ArrayLiteral(Lists.newArrayList(new DateTimeV2Literal("2020-02-02 00:00:00.123"))), + new NullLiteral(), + new DateTimeV2Literal("2020-02-02 00:00:00.12"), + new IntegerLiteral(0), + new ArrayLiteral(Lists.newArrayList(new IntegerLiteral(0)))); + signature = ComputeSignatureHelper.computePrecision(new FakeComputeSignature(), signature, arguments); + Assertions.assertTrue(signature.getArgType(0) instanceof ArrayType); + Assertions.assertEquals(DateTimeV2Type.of(3), + ((ArrayType) signature.getArgType(0)).getItemType()); + Assertions.assertTrue(signature.getArgType(1) instanceof ArrayType); + Assertions.assertEquals(DateTimeV2Type.of(3), + ((ArrayType) signature.getArgType(1)).getItemType()); + Assertions.assertEquals(DateTimeV2Type.of(3), + signature.getArgType(2)); + Assertions.assertTrue(signature.getArgType(4) instanceof ArrayType); + Assertions.assertEquals(IntegerType.INSTANCE, + ((ArrayType) signature.getArgType(4)).getItemType()); + } + + @Test + void testMapDateTimeV2ComputePrecision() { + FunctionSignature signature = FunctionSignature.ret(BooleanType.INSTANCE) + .args(MapType.of(DateTimeV2Type.SYSTEM_DEFAULT, DateTimeV2Type.SYSTEM_DEFAULT), + MapType.of(DateTimeV2Type.SYSTEM_DEFAULT, DateTimeV2Type.SYSTEM_DEFAULT), + DateTimeV2Type.SYSTEM_DEFAULT); + List arguments = Lists.newArrayList( + new MapLiteral(Lists.newArrayList(new DateTimeV2Literal("2020-02-02 00:00:00.123")), + Lists.newArrayList(new DateTimeV2Literal("2020-02-02 00:00:00.12"))), + new NullLiteral(), + new DateTimeV2Literal("2020-02-02 00:00:00.1234")); + signature = ComputeSignatureHelper.computePrecision(new FakeComputeSignature(), signature, arguments); + Assertions.assertTrue(signature.getArgType(0) instanceof MapType); + Assertions.assertEquals(DateTimeV2Type.of(6), + ((MapType) signature.getArgType(0)).getKeyType()); + Assertions.assertEquals(DateTimeV2Type.of(6), + ((MapType) signature.getArgType(0)).getValueType()); + Assertions.assertTrue(signature.getArgType(1) instanceof MapType); + Assertions.assertEquals(DateTimeV2Type.of(6), + ((MapType) signature.getArgType(1)).getKeyType()); + Assertions.assertEquals(DateTimeV2Type.of(6), + ((MapType) signature.getArgType(1)).getValueType()); + Assertions.assertEquals(DateTimeV2Type.of(6), + signature.getArgType(2)); + } + + private static class FakeComputeSignature implements ComputeSignature { + @Override + public List children() { + return null; + } + + @Override + public Expression child(int index) { + return null; + } + + @Override + public int arity() { + return 0; + } + + @Override + public Expression withChildren(List children) { + return null; + } + + @Override + public List getSignatures() { + return null; + } + + @Override + public FunctionSignature getSignature() { + return null; + } + + @Override + public FunctionSignature searchSignature(List signatures) { + return null; + } + + @Override + public boolean nullable() { + return false; + } + } +} diff --git a/regression-test/data/javaudf_p0/test_javaudf_all_types.out b/regression-test/data/javaudf_p0/test_javaudf_all_types.out index e18e1bf1e1bfb0..66c069a699c6bf 100644 --- a/regression-test/data/javaudf_p0/test_javaudf_all_types.out +++ b/regression-test/data/javaudf_p0/test_javaudf_all_types.out @@ -2,12 +2,12 @@ -- !java_udf_all_types -- 1 true 1 2 1 3 4 3.3300 7.77 3.1415 2023-10-18 2023-10-18 2023-10-18 2023-10-11T10:11:11.234 2023-10-11T10:11:11.234 2023-10-11T10:11:11.234 row1 [null, "nested1"] {"k1":null, "k2":1} 2 false 2 4 2 6 8 1.6650 3.885 1.57075 2023-10-19 2023-10-19 2023-10-19 2023-10-12T10:12:11.234 2023-10-12T10:12:11.234 2023-10-12T10:12:11.234 row2 [null, "nested2"] {"k3":2, "k2":null} -3 true 3 6 3 9 12 1.1100 2.59 1.0471666667 2023-10-20 2023-10-20 2023-10-20 2023-10-13T10:13:11.234 2023-10-13T10:13:11.234 2023-10-13T10:13:11.234 row3 [null, "nested3"] {"k3":null, "k4":3} -4 false 4 8 4 12 16 0.8325 1.9425 0.785375 2023-10-21 2023-10-21 2023-10-21 2023-10-14T10:14:11.234 2023-10-14T10:14:11.234 2023-10-14T10:14:11.234 row4 [null, "nested4"] {"k4":null, "k5":4} +3 true 3 6 3 9 12 1.1100 2.59 1.04717 2023-10-20 2023-10-20 2023-10-20 2023-10-13T10:13:11.234 2023-10-13T10:13:11.234 2023-10-13T10:13:11.234 row3 [null, "nested3"] {"k3":null, "k4":3} +4 false 4 8 4 12 16 0.8325 1.943 0.78538 2023-10-21 2023-10-21 2023-10-21 2023-10-14T10:14:11.234 2023-10-14T10:14:11.234 2023-10-14T10:14:11.234 row4 [null, "nested4"] {"k4":null, "k5":4} 5 true 5 10 5 15 20 0.6660 1.554 0.6283 2023-10-22 2023-10-22 2023-10-22 2023-10-15T10:15:11.234 2023-10-15T10:15:11.234 2023-10-15T10:15:11.234 row5 [null, "nested5"] {"k5":null, "k6":5} -6 false 6 12 6 18 24 0.5550 1.295 0.5235833333 2023-10-23 2023-10-23 2023-10-23 2023-10-16T10:16:11.234 2023-10-16T10:16:11.234 2023-10-16T10:16:11.234 row6 [null, "nested6"] {"k7":6, "k6":null} -7 true 7 14 7 21 28 0.4757 1.11 0.4487857143 2023-10-24 2023-10-24 2023-10-24 2023-10-17T10:17:11.234 2023-10-17T10:17:11.234 2023-10-17T10:17:11.234 row7 [null, "nested7"] {"k7":null, "k8":7} -8 false 8 16 8 24 32 0.4163 0.97125 0.3926875 2023-10-25 2023-10-25 2023-10-25 2023-10-18T10:18:11.234 2023-10-18T10:18:11.234 2023-10-18T10:18:11.234 row8 [null, "nested8"] {"k8":null, "k9":8} -9 true 9 18 9 27 36 0.3700 0.86333334 0.3490555556 2023-10-26 2023-10-26 2023-10-26 2023-10-19T10:19:11.234 2023-10-19T10:19:11.234 2023-10-19T10:19:11.234 row9 [null, "nested9"] {"k9":null, "k10":9} +6 false 6 12 6 18 24 0.5550 1.295 0.52358 2023-10-23 2023-10-23 2023-10-23 2023-10-16T10:16:11.234 2023-10-16T10:16:11.234 2023-10-16T10:16:11.234 row6 [null, "nested6"] {"k7":6, "k6":null} +7 true 7 14 7 21 28 0.4757 1.11 0.44879 2023-10-24 2023-10-24 2023-10-24 2023-10-17T10:17:11.234 2023-10-17T10:17:11.234 2023-10-17T10:17:11.234 row7 [null, "nested7"] {"k7":null, "k8":7} +8 false 8 16 8 24 32 0.4163 0.971 0.39269 2023-10-25 2023-10-25 2023-10-25 2023-10-18T10:18:11.234 2023-10-18T10:18:11.234 2023-10-18T10:18:11.234 row8 [null, "nested8"] {"k8":null, "k9":8} +9 true 9 18 9 27 36 0.3700 0.863 0.34906 2023-10-26 2023-10-26 2023-10-26 2023-10-19T10:19:11.234 2023-10-19T10:19:11.234 2023-10-19T10:19:11.234 row9 [null, "nested9"] {"k9":null, "k10":9} 10 false \N 20 10 30 40 \N 0.777 0.31415 \N \N \N 2023-10-20T10:10:11.234 2023-10-20T10:10:11.234 2023-10-20T10:10:11.234 \N [null, "nested10"] {"k11":10, "k10":null} diff --git a/regression-test/data/nereids_function_p0/scalar_function/Array.out b/regression-test/data/nereids_function_p0/scalar_function/Array.out index 9b359ad3e0ffd0..92cb7a24e66c46 100644 --- a/regression-test/data/nereids_function_p0/scalar_function/Array.out +++ b/regression-test/data/nereids_function_p0/scalar_function/Array.out @@ -14204,8 +14204,8 @@ true [] -- !array_apply2 -- -["2022-12-01 22:23:25.000", "2022-12-01 23:23:25.000"] -["2022-12-02 22:23:25.000", "2022-12-02 23:23:25.000"] +["2022-12-01 22:23:25.000000", "2022-12-01 23:23:25.000000"] +["2022-12-02 22:23:25.000000", "2022-12-02 23:23:25.000000"] -- !array_apply3 -- \N diff --git a/regression-test/data/query_p0/aggregate/map_agg_nested_insert_doris.out b/regression-test/data/query_p0/aggregate/map_agg_nested_insert_doris.out index 670124a07a900f..53b23a1d965f3c 100644 --- a/regression-test/data/query_p0/aggregate/map_agg_nested_insert_doris.out +++ b/regression-test/data/query_p0/aggregate/map_agg_nested_insert_doris.out @@ -1,25 +1,25 @@ -- This file is automatically generated. You should know what you did if you want to edit this -- !sql -- -1 LC [0.20961408068486054, 0.67796351365684493, 0.088745389947127551, 0.12660368488966578, 0.50555432] {"RelKZ3-etM12wN-uP4-XR7Z":0.28928123482977663, "FEpfM2-MGtIq1y-Ily-hqLN":0.75982378533995065} -1 LB [0.25076205844319044, 0.54003619330849928, 0.70661164863002113, 0.99472899095144263, 0.07831494] {"UsPMIs-ipxhEnU-1EG-RJpe":0.22741640776012562, "gcn7fm-ILbMhQ6-fcz-TndT":0.36370276228098763, "o8dgBn-1bM26Wz-8SJ-xW6u":0.55671646501523719, "wav6ZA-780SwLJ-Vj3-KCv5":0.8665187582647581} -1 LA [0.35815922932906263, 0.0011899152357573994, 0.28749219850167373, 0.93512930168283781, 0.1552584991620739, 0.733089] {"UsPMIs-ipxhEnU-1EG-RJpe":0.22741640776012562, "gcn7fm-ILbMhQ6-fcz-TndT":0.36370276228098763, "o8dgBn-1bM26Wz-8SJ-xW6u":0.55671646501523719, "wav6ZA-780SwLJ-Vj3-KCv5":0.8665187582647581} +1 LC [0.209614, 0.6779635, 0.0887453, 0.1266036, 0.50555432] {"RelKZ3-etM12wN-uP4-XR7Z":0.289281, "FEpfM2-MGtIq1y-Ily-hqLN":0.759823} +1 LB [0.250762, 0.5400361, 0.7066116, 0.9947289, 0.07831494] {"UsPMIs-ipxhEnU-1EG-RJpe":0.227416, "gcn7fm-ILbMhQ6-fcz-TndT":0.363702, "o8dgBn-1bM26Wz-8SJ-xW6u":0.55671, "wav6ZA-780SwLJ-Vj3-KCv5":0.86651} +1 LA [0.3581592, 0.0011899, 0.2874921, 0.9351293, 0.15525849, 0.733089] {"UsPMIs-ipxhEnU-1EG-RJpe":0.227416, "gcn7fm-ILbMhQ6-fcz-TndT":0.3637, "o8dgBn-1bM26Wz-8SJ-xW6u":0.556716, "wav6ZA-780SwLJ-Vj3-KCv5":0.866518} 2 LC [222, null] {"sUMCB1-rKPSp71-F9O-PyDS":null} -2 LB [null, 1.22344] {null:0.69249939434627483} -2 LA [] {"iK1yJB-yuEElEZ-li4-vxAT":0.43894802430489277, "4kF6cZ-Cwlf33s-eYD-92Dy":0.97378869646008837} -3 LC [1] {"":0.69249939434627483, "sUMCB1-rKPSp71-F9O-S":null} -3 LB [0.20961408068486054, 0] {"4kF6cZ-Cwlf33s-eYD-92Dy":0.97378869646008837, "AyE8nj-ecfHXG1-XuB-ye3B":0.69671634023926254, "CwYJPz-oSaS398-CfV-MOLZ":0.9422562276573786, "xMk5Ob-lCuzA3R-yXs-NLnc":0.31773598018625049} -3 LA [0.20961408068486054, 0.67796351365684493] {null:null, "FEpfM2-MGtIq1y-Ily-hqLN":0.75982378533995065, "Dy4lap-sNXoyV3-LBz-ikjw":0.3353160677758501} +2 LB [null, 1.22344] {null:0.6924} +2 LA [] {"iK1yJB-yuEElEZ-li4-vxAT":0.438948, "4kF6cZ-Cwlf33s-eYD-92Dy":0.97378} +3 LC [1] {"":0.69249, "sUMCB1-rKPSp71-F9O-S":null} +3 LB [0.209614, 0] {"4kF6cZ-Cwlf33s-eYD-92Dy":0.97378, "AyE8nj-ecfHXG1-XuB-ye3B":0.696716, "CwYJPz-oSaS398-CfV-MOLZ":0.94225, "xMk5Ob-lCuzA3R-yXs-NLnc":0.31773} +3 LA [0.209614, 0.6779635] {null:null, "FEpfM2-MGtIq1y-Ily-hqLN":0.7598, "Dy4lap-sNXoyV3-LBz-ikjw":0.33531} 4 LC [4.44, 5.55, 6.66, 7.77] {"a":77, "d":66} 4 LB [1.11, 2.22, 3.33] {"amory":7, "doris":6} -4 LA [0.39467746014773986, 0.68089927382163351, 0.17672102367531073, 0.075743536456418625] {"kduA0V-rqJ4ga1-mvG-p3OK":0.0980960662977799, "xpDNOl-iTcYRWk-6Ak-9smj":0.81335421914074846} +4 LA [0.39464, 0.68089, 0.17672, 0.0757435] {"kduA0V-rqJ4ga1-mvG-p3OK":0.098096, "xpDNOl-iTcYRWk-6Ak-9smj":0.813354} 5 LC [1, 3, 7] {"a":3, "up":7} -5 LB [0.68817051068356083, 0.58866705765486893, 0.9770647663621238] {"CDuRMK-JH8MfuY-ogq-QiQS":0.061575881523062148, "3WYdO0-XltW1HK-hjM-LNlz":0.86164972492374081, "SxBfEK-pIiMQV6-qwZ-B2rj":0.80341434305286941} +5 LB [0.68817, 0.588667, 0.97706] {"CDuRMK-JH8MfuY-ogq-QiQS":0.0615758, "3WYdO0-XltW1HK-hjM-LNlz":0.8616, "SxBfEK-pIiMQV6-qwZ-B2rj":0.80341} 5 LA [1234.3456, 345.3453456] {"":null} -- !sql -- -1 {"LC":[0.20961408068486054, 0.67796351365684493, 0.088745389947127551, 0.12660368488966578, 0.50555432], "LB":[0.25076205844319044, 0.54003619330849928, 0.70661164863002113, 0.99472899095144263, 0.07831494], "LA":[0.35815922932906263, 0.0011899152357573994, 0.28749219850167373, 0.93512930168283781, 0.1552584991620739, 0.733089]} +1 {"LC":[0.209614, 0.6779635, 0.0887453, 0.1266036, 0.50555432], "LB":[0.250762, 0.5400361, 0.7066116, 0.9947289, 0.07831494], "LA":[0.3581592, 0.0011899, 0.2874921, 0.9351293, 0.15525849, 0.733089]} 2 {"LC":[222, null], "LB":[null, 1.22344], "LA":[]} -3 {"LC":[1], "LB":[0.20961408068486054, 0], "LA":[0.20961408068486054, 0.67796351365684493]} -4 {"LC":[4.44, 5.55, 6.66, 7.77], "LB":[1.11, 2.22, 3.33], "LA":[0.39467746014773986, 0.68089927382163351, 0.17672102367531073, 0.075743536456418625]} -5 {"LC":[1, 3, 7], "LB":[0.68817051068356083, 0.58866705765486893, 0.9770647663621238], "LA":[1234.3456, 345.3453456]} +3 {"LC":[1], "LB":[0.209614, 0], "LA":[0.209614, 0.6779635]} +4 {"LC":[4.44, 5.55, 6.66, 7.77], "LB":[1.11, 2.22, 3.33], "LA":[0.39464, 0.68089, 0.17672, 0.0757435]} +5 {"LC":[1, 3, 7], "LB":[0.68817, 0.588667, 0.97706], "LA":[1234.3456, 345.3453456]} diff --git a/regression-test/data/query_p0/sql_functions/array_functions/test_array_with_scale_type.out b/regression-test/data/query_p0/sql_functions/array_functions/test_array_with_scale_type.out index cb0adda716a301..811aba2040c6e6 100644 --- a/regression-test/data/query_p0/sql_functions/array_functions/test_array_with_scale_type.out +++ b/regression-test/data/query_p0/sql_functions/array_functions/test_array_with_scale_type.out @@ -91,8 +91,8 @@ [] -- !select -- -["2022-12-01 22:23:25.000", "2022-12-01 23:23:25.000"] -["2022-12-02 22:23:25.000", "2022-12-02 23:23:25.000"] +["2022-12-01 22:23:25.000000", "2022-12-01 23:23:25.000000"] +["2022-12-02 22:23:25.000000", "2022-12-02 23:23:25.000000"] -- !select -- \N @@ -119,8 +119,8 @@ ["2022-12-02 22:23:25.000", "2022-12-02 23:23:25.000"] -- !select -- -["2022-12-01 22:23:25.000", "2022-12-01 23:23:25.000", "2022-12-02 22:23:24.123", "2022-12-02 22:23:23.123"] -["2022-12-02 22:23:25.000", "2022-12-02 23:23:25.000", "2022-12-02 22:23:24.123", "2022-12-02 22:23:23.123"] +["2022-12-01 22:23:25.000000", "2022-12-01 23:23:25.000000", "2022-12-02 22:23:24.123000", "2022-12-02 22:23:23.123000"] +["2022-12-02 22:23:25.000000", "2022-12-02 23:23:25.000000", "2022-12-02 22:23:24.123000", "2022-12-02 22:23:23.123000"] -- !select -- [22.679, 33.679, 22.679, 33.679, 22.679, 33.679] diff --git a/regression-test/suites/javaudf_p0/test_javaudf_all_types.groovy b/regression-test/suites/javaudf_p0/test_javaudf_all_types.groovy index 46823eb2767f64..736f52d5c37d8f 100644 --- a/regression-test/suites/javaudf_p0/test_javaudf_all_types.groovy +++ b/regression-test/suites/javaudf_p0/test_javaudf_all_types.groovy @@ -51,11 +51,11 @@ suite("test_javaudf_all_types") { int i = 1 for (; i < 10; i++) { sb.append(""" - (${i},${i%2},${i},${i}*2,${i}*3,${i}*4,${3.33/i},${7.77/i},${3.1415/i},"2023-10-${i+17}","2023-10-${i+10} 10:1${i}:11.234","row${i}",array(null, "nested${i}"),{"k${i}":null,"k${i+1}":${i}}), + (${i},${i%2},${i},${i}*2,${i}*3,${i}*4,${3.33/i},${(7.77/i).round(3)},${(3.1415/i).round(5)},"2023-10-${i+17}","2023-10-${i+10} 10:1${i}:11.234","row${i}",array(null, "nested${i}"),{"k${i}":null,"k${i+1}":${i}}), """) } sb.append(""" - (${i},${i%2},null,${i}*2,${i}*3,${i}*4,null,${7.77/i},${3.1415/i},null,"2023-10-${i+10} 10:${i}:11.234",null,array(null, "nested${i}"),{"k${i}":null,"k${i+1}":${i}}) + (${i},${i%2},null,${i}*2,${i}*3,${i}*4,null,${(7.77/i).round(3)},${(3.1415/i).round(5)},null,"2023-10-${i+10} 10:${i}:11.234",null,array(null, "nested${i}"),{"k${i}":null,"k${i+1}":${i}}) """) sql """ INSERT INTO ${tableName} VALUES ${sb.toString()} diff --git a/regression-test/suites/query_p0/aggregate/map_agg_nested_insert_doris.groovy b/regression-test/suites/query_p0/aggregate/map_agg_nested_insert_doris.groovy index dc0de44257e3bf..a4b0410cba3a31 100644 --- a/regression-test/suites/query_p0/aggregate/map_agg_nested_insert_doris.groovy +++ b/regression-test/suites/query_p0/aggregate/map_agg_nested_insert_doris.groovy @@ -60,20 +60,20 @@ suite("map_agg_nested_insert_doris", "p0") { sql """ insert into `${tb_base}` values - (1, "LA", [0.35815922932906263, 0.0011899152357573994, 0.28749219850167373, 0.93512930168283781, 0.1552584991620739, 0.733089], {"UsPMIs-ipxhEnU-1EG-RJpe":0.22741640776012562, "gcn7fm-ILbMhQ6-fcz-TndT":0.36370276228098763, "o8dgBn-1bM26Wz-8SJ-xW6u":0.55671646501523719, "wav6ZA-780SwLJ-Vj3-KCv5":0.8665187582647581}), - (1, "LB", [0.25076205844319044, 0.54003619330849928, 0.70661164863002113, 0.99472899095144263, 0.07831494], {"UsPMIs-ipxhEnU-1EG-RJpe":0.22741640776012562, "gcn7fm-ILbMhQ6-fcz-TndT":0.36370276228098763, "o8dgBn-1bM26Wz-8SJ-xW6u":0.55671646501523719, "wav6ZA-780SwLJ-Vj3-KCv5":0.8665187582647581}), - (1, "LC", [0.20961408068486054, 0.67796351365684493, 0.088745389947127551, 0.12660368488966578, 0.50555432], {"RelKZ3-etM12wN-uP4-XR7Z":0.28928123482977663, "FEpfM2-MGtIq1y-Ily-hqLN":0.75982378533995065}), - (2, "LA", [], {"iK1yJB-yuEElEZ-li4-vxAT":0.43894802430489277, "4kF6cZ-Cwlf33s-eYD-92Dy":0.97378869646008837}), - (2, "LB", [NULL, 1.22344], {NULL: 0.69249939434627483}), + (1, "LA", [0.3581592, 0.0011899, 0.2874921, 0.9351293, 0.15525849, 0.733089], {"UsPMIs-ipxhEnU-1EG-RJpe":0.227416, "gcn7fm-ILbMhQ6-fcz-TndT":0.36370, "o8dgBn-1bM26Wz-8SJ-xW6u":0.556716, "wav6ZA-780SwLJ-Vj3-KCv5":0.866518}), + (1, "LB", [0.2507620, 0.5400361, 0.7066116, 0.9947289, 0.07831494], {"UsPMIs-ipxhEnU-1EG-RJpe":0.227416, "gcn7fm-ILbMhQ6-fcz-TndT":0.363702, "o8dgBn-1bM26Wz-8SJ-xW6u":0.55671, "wav6ZA-780SwLJ-Vj3-KCv5":0.86651}), + (1, "LC", [0.2096140, 0.6779635, 0.0887453, 0.1266036, 0.50555432], {"RelKZ3-etM12wN-uP4-XR7Z":0.289281, "FEpfM2-MGtIq1y-Ily-hqLN":0.759823}), + (2, "LA", [], {"iK1yJB-yuEElEZ-li4-vxAT":0.4389480, "4kF6cZ-Cwlf33s-eYD-92Dy":0.97378}), + (2, "LB", [NULL, 1.22344], {NULL: 0.6924}), (2, "LC", [222,NULL], {"sUMCB1-rKPSp71-F9O-PyDS": NULL}), - (3, "LA", [0.20961408068486054, 0.67796351365684493], {NULL:NULL, "FEpfM2-MGtIq1y-Ily-hqLN":0.75982378533995065, "Dy4lap-sNXoyV3-LBz-ikjw":0.3353160677758501}), - (3, "LB", [0.20961408068486054,0], {"4kF6cZ-Cwlf33s-eYD-92Dy":0.97378869646008837, "AyE8nj-ecfHXG1-XuB-ye3B":0.69671634023926254, "CwYJPz-oSaS398-CfV-MOLZ":0.9422562276573786, "xMk5Ob-lCuzA3R-yXs-NLnc":0.31773598018625049}), - (3, "LC", [1.], {"" : 0.69249939434627483, "sUMCB1-rKPSp71-F9O-S":NULL}), - (4, "LA", [0.39467746014773986, 0.68089927382163351, 0.17672102367531073, 0.075743536456418625], {"kduA0V-rqJ4ga1-mvG-p3OK":0.0980960662977799, "xpDNOl-iTcYRWk-6Ak-9smj":0.81335421914074846}), + (3, "LA", [0.2096140, 0.6779635], {NULL:NULL, "FEpfM2-MGtIq1y-Ily-hqLN":0.7598, "Dy4lap-sNXoyV3-LBz-ikjw":0.33531}), + (3, "LB", [0.2096140,0], {"4kF6cZ-Cwlf33s-eYD-92Dy":0.97378, "AyE8nj-ecfHXG1-XuB-ye3B":0.696716, "CwYJPz-oSaS398-CfV-MOLZ":0.94225, "xMk5Ob-lCuzA3R-yXs-NLnc":0.31773}), + (3, "LC", [1.], {"" : 0.69249, "sUMCB1-rKPSp71-F9O-S":NULL}), + (4, "LA", [0.39464, 0.68089, 0.17672, 0.0757435], {"kduA0V-rqJ4ga1-mvG-p3OK":0.0980960, "xpDNOl-iTcYRWk-6Ak-9smj":0.813354}), (4, "LB", [1.11, 2.22, 3.33], {"amory": 7, "doris": 6}), (4, "LC", [4.44, 5.55, 6.66, 7.77], {"a": 77, "d": 66}), (5, "LA", [1234.3456, 345.3453456], {"":NULL}), - (5, "LB", [0.68817051068356083, 0.58866705765486893, 0.9770647663621238], {"CDuRMK-JH8MfuY-ogq-QiQS":0.061575881523062148, "3WYdO0-XltW1HK-hjM-LNlz":0.86164972492374081, "SxBfEK-pIiMQV6-qwZ-B2rj":0.80341434305286941}), + (5, "LB", [0.688170, 0.5886670, 0.97706], {"CDuRMK-JH8MfuY-ogq-QiQS":0.0615758, "3WYdO0-XltW1HK-hjM-LNlz":0.8616, "SxBfEK-pIiMQV6-qwZ-B2rj":0.80341}), (5, "LC", [1, 3, 7], {"a": 3, "up": 7}); """