diff --git a/fe/fe-core/src/main/java/org/apache/doris/analysis/ArrayLiteral.java b/fe/fe-core/src/main/java/org/apache/doris/analysis/ArrayLiteral.java index 415a4b6067..7edba5d609 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/analysis/ArrayLiteral.java +++ b/fe/fe-core/src/main/java/org/apache/doris/analysis/ArrayLiteral.java @@ -18,6 +18,7 @@ package org.apache.doris.analysis; import org.apache.doris.catalog.ArrayType; +import org.apache.doris.catalog.ScalarType; import org.apache.doris.catalog.Type; import org.apache.doris.common.AnalysisException; import org.apache.doris.thrift.TExprNode; @@ -129,6 +130,22 @@ public class ArrayLiteral extends LiteralExpr { return "[" + StringUtils.join(list, ", ") + "]"; } + @Override + public String getStringValueInFe() { + List list = new ArrayList<>(children.size()); + children.forEach(v -> { + // we should use type to decide we output array is suitable for json format + if (!(v instanceof NullLiteral) && v.getType().isScalarType() + && (Type.getNumericTypes().contains((ScalarType) v.getActualScalarType(v.getType())) + || v.getType() == Type.BOOLEAN)) { + list.add(v.getStringValueInFe()); + } else { + list.add(v.getStringValueForArray()); + } + }); + return "[" + StringUtils.join(list, ", ") + "]"; + } + @Override protected void toThrift(TExprNode msg) { msg.node_type = TExprNodeType.ARRAY_LITERAL; 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 0762f3191f..250bee7e8e 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 @@ -246,6 +246,11 @@ public class DecimalLiteral extends LiteralExpr { } } + @Override + public String getStringValueInFe() { + return value.toPlainString(); + } + @Override public String toSqlImpl() { return getStringValue(); diff --git a/fe/fe-core/src/main/java/org/apache/doris/analysis/Expr.java b/fe/fe-core/src/main/java/org/apache/doris/analysis/Expr.java index fc4e46d314..465f96c37d 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/analysis/Expr.java +++ b/fe/fe-core/src/main/java/org/apache/doris/analysis/Expr.java @@ -2224,6 +2224,10 @@ public abstract class Expr extends TreeNode implements ParseNode, Cloneabl return ""; } + public String getStringValueInFe() { + return getStringValue(); + } + // A special method only for array literal, all primitive type in array // will be wrapped by double quote. eg: // ["1", "2", "3"] diff --git a/fe/fe-core/src/main/java/org/apache/doris/analysis/FloatLiteral.java b/fe/fe-core/src/main/java/org/apache/doris/analysis/FloatLiteral.java index c87505b22d..b95b3860aa 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/analysis/FloatLiteral.java +++ b/fe/fe-core/src/main/java/org/apache/doris/analysis/FloatLiteral.java @@ -140,9 +140,26 @@ public class FloatLiteral extends LiteralExpr { return nf.format(value); } + @Override + public String getStringValueInFe() { + if (type == Type.TIME || type == Type.TIMEV2) { + // FloatLiteral used to represent TIME type, here we need to remove apostrophe from timeStr + // for example '11:22:33' -> 11:22:33 + String timeStr = getStringValue(); + return timeStr.substring(1, timeStr.length() - 1); + } else { + return BigDecimal.valueOf(getValue()).toPlainString(); + } + } + @Override public String getStringValueForArray() { - return "\"" + getStringValue() + "\""; + String ret = getStringValue(); + if (type == Type.TIME || type == Type.TIMEV2) { + // here already wrapped in '' + ret = ret.substring(1, ret.length() - 1); + } + return "\"" + ret + "\""; } public static Type getDefaultTimeType(Type type) throws AnalysisException { diff --git a/fe/fe-core/src/main/java/org/apache/doris/analysis/LiteralExpr.java b/fe/fe-core/src/main/java/org/apache/doris/analysis/LiteralExpr.java index 7047a8d900..28da8d2d20 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/analysis/LiteralExpr.java +++ b/fe/fe-core/src/main/java/org/apache/doris/analysis/LiteralExpr.java @@ -234,6 +234,10 @@ public abstract class LiteralExpr extends Expr implements Comparable data) { - if (literalExpr instanceof NullLiteral) { - data.add(null); - } else if (literalExpr instanceof FloatLiteral) { - data.add(LiteralUtils.getStringValue((FloatLiteral) literalExpr)); - } else if (literalExpr instanceof DecimalLiteral) { - data.add(((DecimalLiteral) literalExpr).getValue().toPlainString()); - } else if (literalExpr instanceof ArrayLiteral) { - data.add(LiteralUtils.getStringValue((ArrayLiteral) literalExpr)); - } else { - data.add(literalExpr.getStringValue()); - } - } - public void appendTupleInfo(StringBuilder stringBuilder) {} public void appendHintInfo(StringBuilder stringBuilder) {} diff --git a/fe/fe-core/src/test/java/org/apache/doris/analysis/ArrayLiteralTest.java b/fe/fe-core/src/test/java/org/apache/doris/analysis/ArrayLiteralTest.java index 53b9ede98d..fb9c6f0e18 100644 --- a/fe/fe-core/src/test/java/org/apache/doris/analysis/ArrayLiteralTest.java +++ b/fe/fe-core/src/test/java/org/apache/doris/analysis/ArrayLiteralTest.java @@ -62,4 +62,63 @@ public class ArrayLiteralTest { ArrayLiteral arrayLiteral9 = new ArrayLiteral(); Assert.assertEquals("[]", arrayLiteral9.getStringValueForArray()); } + + + @Test + public void testGetStringInFe() throws AnalysisException { + IntLiteral intLiteral1 = new IntLiteral(1); + FloatLiteral floatLiteral = new FloatLiteral("2.15"); + FloatLiteral floatLiteral1 = new FloatLiteral((double) (11 * 3600 + 22 * 60 + 33), + FloatLiteral.getDefaultTimeType(Type.TIME)); + + BoolLiteral boolLiteral = new BoolLiteral(true); + StringLiteral stringLiteral = new StringLiteral("shortstring"); + LargeIntLiteral largeIntLiteral = new LargeIntLiteral("1000000000000000000000"); + NullLiteral nullLiteral = new NullLiteral(); + DateLiteral dateLiteral = new DateLiteral("2022-10-10", Type.DATE); + DateLiteral datetimeLiteral = new DateLiteral("2022-10-10 12:10:10", Type.DATETIME); + ArrayLiteral arrayLiteral1 = new ArrayLiteral(intLiteral1, floatLiteral); + Assert.assertEquals("[1.0, 2.15]", arrayLiteral1.getStringValueInFe()); + ArrayLiteral arrayLiteralWithTime = new ArrayLiteral(floatLiteral1); + Assert.assertEquals("[\"11:22:33\"]", arrayLiteralWithTime.getStringValueInFe()); + + ArrayLiteral arrayLiteral2 = new ArrayLiteral(boolLiteral, boolLiteral); + Assert.assertEquals("[1, 1]", arrayLiteral2.getStringValueInFe()); + + ArrayLiteral arrayLiteral3 = new ArrayLiteral(stringLiteral, stringLiteral); + Assert.assertEquals("[\"shortstring\", \"shortstring\"]", arrayLiteral3.getStringValueInFe()); + + ArrayLiteral arrayLiteral4 = new ArrayLiteral(largeIntLiteral, largeIntLiteral); + Assert.assertEquals("[1000000000000000000000, 1000000000000000000000]", arrayLiteral4.getStringValueInFe()); + + ArrayLiteral arrayLiteral5 = new ArrayLiteral(nullLiteral, nullLiteral); + Assert.assertEquals("[null, null]", arrayLiteral5.getStringValueInFe()); + + ArrayLiteral arrayLiteral6 = new ArrayLiteral(dateLiteral, dateLiteral); + Assert.assertEquals("[\"2022-10-10\", \"2022-10-10\"]", arrayLiteral6.getStringValueInFe()); + + ArrayLiteral arrayLiteral7 = new ArrayLiteral(datetimeLiteral, datetimeLiteral); + Assert.assertEquals("[\"2022-10-10 12:10:10\", \"2022-10-10 12:10:10\"]", arrayLiteral7.getStringValueInFe()); + + ArrayLiteral arrayLiteral8 = new ArrayLiteral(arrayLiteral7, arrayLiteral7); + Assert.assertEquals("[[\"2022-10-10 12:10:10\", \"2022-10-10 12:10:10\"], [\"2022-10-10 12:10:10\", \"2022-10-10 12:10:10\"]]", + arrayLiteral8.getStringValueInFe()); + + ArrayLiteral arrayLiteral9 = new ArrayLiteral(); + Assert.assertEquals("[]", arrayLiteral9.getStringValueInFe()); + + DecimalLiteral decimalLiteral = new DecimalLiteral("1.0"); + DecimalLiteral decimalLiteral2 = new DecimalLiteral("2"); + ArrayLiteral arrayLiteral10 = new ArrayLiteral(decimalLiteral, decimalLiteral2); + Assert.assertEquals("[1.0, 2.0]", arrayLiteral10.getStringValueInFe()); + + //array(1, null) + IntLiteral intLiteralWithNull = new IntLiteral(1); + ArrayLiteral arrayLiteral11 = new ArrayLiteral(intLiteralWithNull, nullLiteral); + Assert.assertEquals("[1, null]", arrayLiteral11.getStringValueInFe()); + //array(null, 1) + ArrayLiteral arrayLiteral12 = new ArrayLiteral(nullLiteral, intLiteralWithNull); + Assert.assertEquals("[null, 1]", arrayLiteral12.getStringValueInFe()); + + } } diff --git a/fe/fe-core/src/test/java/org/apache/doris/analysis/DateLiteralTest.java b/fe/fe-core/src/test/java/org/apache/doris/analysis/DateLiteralTest.java index 9715b7a182..556c8a5245 100644 --- a/fe/fe-core/src/test/java/org/apache/doris/analysis/DateLiteralTest.java +++ b/fe/fe-core/src/test/java/org/apache/doris/analysis/DateLiteralTest.java @@ -28,6 +28,14 @@ import org.junit.Test; public class DateLiteralTest { + @Test + public void testGetStringInFe() throws AnalysisException { + DateLiteral literal = new DateLiteral("1997-10-07", Type.DATE); + String s = literal.getStringValueInFe(); + Assert.assertEquals(s, "1997-10-07"); + + } + @Test public void twoDigitYear() { boolean hasException = false; 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 11cccf25bf..bd7ca08e34 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 @@ -31,6 +31,14 @@ import java.nio.ByteBuffer; public class DecimalLiteralTest { + @Test + public void testGetStringInFe() { + BigDecimal decimal = new BigDecimal("-123456789123456789.123456789"); + DecimalLiteral literal = new DecimalLiteral(decimal); + String s = literal.getStringValueInFe(); + Assert.assertEquals("-123456789123456789.123456789", s); + } + @Test public void testHashValue() throws AnalysisException { BigDecimal decimal = new BigDecimal("-123456789123456789.123456789"); diff --git a/fe/fe-core/src/test/java/org/apache/doris/analysis/FloatLiteralTest.java b/fe/fe-core/src/test/java/org/apache/doris/analysis/FloatLiteralTest.java new file mode 100644 index 0000000000..6b7bfedbb5 --- /dev/null +++ b/fe/fe-core/src/test/java/org/apache/doris/analysis/FloatLiteralTest.java @@ -0,0 +1,39 @@ +// 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.analysis; + +import org.apache.doris.catalog.Type; +import org.apache.doris.common.AnalysisException; + +import org.junit.Assert; +import org.junit.Test; + + +public class FloatLiteralTest { + @Test + public void testGetStringInFe() throws AnalysisException { + FloatLiteral literal = new FloatLiteral((double) (11 * 3600 + 22 * 60 + 33), + FloatLiteral.getDefaultTimeType(Type.TIME)); + String s = literal.getStringValueInFe(); + Assert.assertEquals("11:22:33", s); + + FloatLiteral literal1 = new FloatLiteral(11.22); + String s1 = literal1.getStringValueInFe(); + Assert.assertEquals("11.22", s1); + } +} diff --git a/regression-test/data/query_p0/sql_functions/array_functions/test_array_functions_by_literal.out b/regression-test/data/query_p0/sql_functions/array_functions/test_array_functions_by_literal.out index 387c0beb96..e90b40f61c 100644 --- a/regression-test/data/query_p0/sql_functions/array_functions/test_array_functions_by_literal.out +++ b/regression-test/data/query_p0/sql_functions/array_functions/test_array_functions_by_literal.out @@ -801,7 +801,7 @@ _ ["a", "1", "2"] -- !sql -- -[NULL, NULL, NULL] +[null, null, null] -- !sql -- [] 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 811aba2040..a953584121 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 @@ -84,7 +84,7 @@ ["2022-12-02 22:23:25.000", "2022-12-02 22:23:23.998"] -- !select -- -[2022-12-02 22:23:25, 2022-12-02 22:23:23.998] +["2022-12-02 22:23:25", "2022-12-02 22:23:23.998"] -- !select -- [] diff --git a/regression-test/data/query_p0/sql_functions/conditional_functions/test_if_cast.out b/regression-test/data/query_p0/sql_functions/conditional_functions/test_if_cast.out index 1fb288a763..255c00df0e 100644 --- a/regression-test/data/query_p0/sql_functions/conditional_functions/test_if_cast.out +++ b/regression-test/data/query_p0/sql_functions/conditional_functions/test_if_cast.out @@ -15,5 +15,23 @@ ["1970-01-01"] -- !select -- -[NULL] +[null] + +-- !select_nereid -- +["1970-01-01", "1970-01-01"] + +-- !select_nereid -- +["1970-01-01", "1970-01-01"] + +-- !select_nereid -- +["1970-01-01", "1970-01-01"] + +-- !select_nereid -- +[] + +-- !select_nereid -- +["1970-01-01"] + +-- !select_nereid -- +[null] diff --git a/regression-test/suites/nereids_syntax_p0/array_function.groovy b/regression-test/suites/nereids_syntax_p0/array_function.groovy index e05dd92ec9..fb883c94f2 100644 --- a/regression-test/suites/nereids_syntax_p0/array_function.groovy +++ b/regression-test/suites/nereids_syntax_p0/array_function.groovy @@ -25,8 +25,9 @@ suite("array_function") { qt_4 "SELECT ARRAY_MAP(x->x+1, ARRAY(-82.31, -72.18, 35.59, -67.13))" qt_5 "SELECT ARRAY_MAP((x,y)->x+y, ARRAY(-37.03, 81.89, 56.38, -36.76), ARRAY(1.56, -14.58, 42.22, -56.13))" test { + // array nested null show lower sql "select array(), array(null), array(1), array('abc'), array(null, 1), array(1, null)" - result([["[]", "[NULL]", "[1]", "[\"abc\"]", "[NULL, 1]", "[1, NULL]"]]) + result([["[]", "[null]", "[1]", "[\"abc\"]", "[null, 1]", "[1, null]"]]) } test { diff --git a/regression-test/suites/query_p0/sql_functions/conditional_functions/test_if_cast.groovy b/regression-test/suites/query_p0/sql_functions/conditional_functions/test_if_cast.groovy index 1b00082394..2c6116c094 100644 --- a/regression-test/suites/query_p0/sql_functions/conditional_functions/test_if_cast.groovy +++ b/regression-test/suites/query_p0/sql_functions/conditional_functions/test_if_cast.groovy @@ -16,10 +16,24 @@ // under the License. suite("test_if_cast") { + // test old planner + sql "set enable_nereids_planner=false" qt_select """ select if(job_d is null, cast(array() as array), job_d) as test from (select array('1970-01-01', '1970-01-01') as job_d) t; """ qt_select """ select if(job_d is null, cast(array(null) as array), job_d) as test from (select array('1970-01-01', '1970-01-01') as job_d) t; """ qt_select """ select if(job_d is null, cast(array('1970-01-01') as array), job_d) as test from (select array('1970-01-01', '1970-01-01') as job_d) t; """ qt_select """ select if(job_d is null, job_d, cast(array() as array)) as test from (select array('1970-01-01', '1970-01-01') as job_d) t; """ qt_select """ select if(job_d is null, job_d, cast(array('1970-01-01') as array)) as test from (select array('1970-01-01', '1970-01-01') as job_d) t; """ qt_select """ select if(job_d is null, job_d, cast(array(null) as array)) as test from (select array('1970-01-01', '1970-01-01') as job_d) t; """ + + // test new planner + sql "set enable_nereids_planner=true" + sql "set enable_fallback_to_original_planner = false" + qt_select_nereid """ select if(job_d is null, cast(array() as array), job_d) as test from (select array('1970-01-01', '1970-01-01') as job_d) t; """ + qt_select_nereid """ select if(job_d is null, cast(array(null) as array), job_d) as test from (select array('1970-01-01', '1970-01-01') as job_d) t; """ + qt_select_nereid """ select if(job_d is null, cast(array('1970-01-01') as array), job_d) as test from (select array('1970-01-01', '1970-01-01') as job_d) t; """ + qt_select_nereid """ select if(job_d is null, job_d, cast(array() as array)) as test from (select array('1970-01-01', '1970-01-01') as job_d) t; """ + qt_select_nereid """ select if(job_d is null, job_d, cast(array('1970-01-01') as array)) as test from (select array('1970-01-01', '1970-01-01') as job_d) t; """ + qt_select_nereid """ select if(job_d is null, job_d, cast(array(null) as array)) as test from (select array('1970-01-01', '1970-01-01') as job_d) t; """ + + }