From f0bb012dd25e373a25d3ed948cfd260a1bbc8795 Mon Sep 17 00:00:00 2001 From: HappenLee Date: Sun, 4 Oct 2020 10:24:36 +0800 Subject: [PATCH] [Bug] Fix Windows function lag()/lead() function throw AnalysisException. (#4666) Add lag() and lead() char and varchar check in `isCastMatchAllowed`. --- .../apache/doris/analysis/DecimalLiteral.java | 4 +- .../org/apache/doris/catalog/FunctionSet.java | 4 +- .../doris/analysis/DecimalLiteralTest.java | 9 +++- .../apache/doris/catalog/FunctionSetTest.java | 53 +++++++++++++++++++ 4 files changed, 67 insertions(+), 3 deletions(-) create mode 100644 fe/fe-core/src/test/java/org/apache/doris/catalog/FunctionSetTest.java diff --git a/fe/fe-core/src/main/java/org/apache/doris/analysis/DecimalLiteral.java b/fe/fe-core/src/main/java/org/apache/doris/analysis/DecimalLiteral.java index 796e31ed0f..66d4b0531a 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/analysis/DecimalLiteral.java +++ b/fe/fe-core/src/main/java/org/apache/doris/analysis/DecimalLiteral.java @@ -224,7 +224,9 @@ public class DecimalLiteral extends LiteralExpr { @Override protected Expr uncheckedCastTo(Type targetType) throws AnalysisException { - if (targetType.isFloatingPointType()) { + if (targetType.isDecimal() || targetType.isDecimalV2()) { + return this; + } else if (targetType.isFloatingPointType()) { return new FloatLiteral(value.doubleValue(), targetType); } else if (targetType.isIntegerType()) { return new IntLiteral(value.longValue(), targetType); diff --git a/fe/fe-core/src/main/java/org/apache/doris/catalog/FunctionSet.java b/fe/fe-core/src/main/java/org/apache/doris/catalog/FunctionSet.java index 67436cf75e..77707a4db6 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/catalog/FunctionSet.java +++ b/fe/fe-core/src/main/java/org/apache/doris/catalog/FunctionSet.java @@ -754,7 +754,9 @@ public class FunctionSet { final Type[] candicateArgTypes = candicate.getArgs(); if (functionName.equalsIgnoreCase("hex") || functionName.equalsIgnoreCase("greast") - || functionName.equalsIgnoreCase("least")) { + || functionName.equalsIgnoreCase("least") + || functionName.equalsIgnoreCase("lead") + || functionName.equalsIgnoreCase("lag")) { final ScalarType descArgType = (ScalarType)descArgTypes[0]; final ScalarType candicateArgType = (ScalarType)candicateArgTypes[0]; if (!descArgType.isStringType() && candicateArgType.isStringType()) { diff --git a/fe/fe-core/src/test/java/org/apache/doris/analysis/DecimalLiteralTest.java b/fe/fe-core/src/test/java/org/apache/doris/analysis/DecimalLiteralTest.java index 20d1d51421..3faf0b6245 100644 --- a/fe/fe-core/src/test/java/org/apache/doris/analysis/DecimalLiteralTest.java +++ b/fe/fe-core/src/test/java/org/apache/doris/analysis/DecimalLiteralTest.java @@ -19,6 +19,8 @@ package org.apache.doris.analysis; import org.apache.doris.catalog.PrimitiveType; +import org.apache.doris.catalog.Type; +import org.apache.doris.common.AnalysisException; import org.junit.Assert; import org.junit.Test; @@ -28,7 +30,7 @@ import java.nio.ByteBuffer; public class DecimalLiteralTest { @Test - public void testHashValue() { + public void testHashValue() throws AnalysisException { BigDecimal decimal = new BigDecimal("-123456789123456789.123456789"); DecimalLiteral literal = new DecimalLiteral(decimal); @@ -40,6 +42,11 @@ public class DecimalLiteralTest { Assert.assertEquals(-123456789123456789L, longValue); Assert.assertEquals(-123456789, fracValue); + // if DecimalLiteral need to cast to Decimal and Decimalv2, need to cast + // to themselves + Assert.assertEquals(literal, literal.uncheckedCastTo(Type.DECIMAL)); + Assert.assertEquals(literal, literal.uncheckedCastTo(Type.DECIMALV2)); + Assert.assertEquals(1, literal.compareLiteral(new NullLiteral())); } } diff --git a/fe/fe-core/src/test/java/org/apache/doris/catalog/FunctionSetTest.java b/fe/fe-core/src/test/java/org/apache/doris/catalog/FunctionSetTest.java new file mode 100644 index 0000000000..e1b6e68eb6 --- /dev/null +++ b/fe/fe-core/src/test/java/org/apache/doris/catalog/FunctionSetTest.java @@ -0,0 +1,53 @@ +// 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.catalog; + +import org.apache.doris.analysis.FunctionName; + +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +public class FunctionSetTest { + + private FunctionSet functionSet; + + @Before + public void setUp() { + functionSet = new FunctionSet(); + functionSet.init(); + } + + @Test + public void testGetLagFunction() { + Type[] argTypes1 = {ScalarType.DECIMAL, ScalarType.TINYINT, ScalarType.TINYINT}; + Function lagDesc1 = new Function(new FunctionName("lag"), argTypes1, (Type) ScalarType.INVALID, false); + Function newFunction = functionSet.getFunction(lagDesc1, Function.CompareMode.IS_SUPERTYPE_OF); + Type[] newArgTypes = newFunction.getArgs(); + Assert.assertTrue(newArgTypes[0].matchesType(newArgTypes[2])); + Assert.assertTrue(newArgTypes[0].matchesType(ScalarType.DECIMAL)); + + Type[] argTypes2 = {ScalarType.VARCHAR, ScalarType.TINYINT, ScalarType.TINYINT}; + Function lagDesc2 = new Function(new FunctionName("lag"), argTypes2, (Type) ScalarType.INVALID, false); + newFunction = functionSet.getFunction(lagDesc2, Function.CompareMode.IS_SUPERTYPE_OF); + newArgTypes = newFunction.getArgs(); + Assert.assertTrue(newArgTypes[0].matchesType(newArgTypes[2])); + Assert.assertTrue(newArgTypes[0].matchesType(ScalarType.VARCHAR)); + } + +} \ No newline at end of file