This is an automated email from the ASF dual-hosted git repository. yiguolei pushed a commit to branch branch-2.0 in repository https://gitbox.apache.org/repos/asf/doris.git
The following commit(s) were added to refs/heads/branch-2.0 by this push: new 943ba153f55 [FIX](complextype) update complex nested support complex type in fe (#29548) 943ba153f55 is described below commit 943ba153f5571a5b94bc310f845aceadf593096d Author: amory <amorywang...@gmail.com> AuthorDate: Sat Jan 6 15:50:21 2024 +0800 [FIX](complextype) update complex nested support complex type in fe (#29548) --- .../main/java/org/apache/doris/catalog/Type.java | 17 +++ .../org/apache/doris/analysis/ArrayLiteral.java | 13 ++ .../org/apache/doris/analysis/DecimalLiteral.java | 5 + .../main/java/org/apache/doris/analysis/Expr.java | 4 + .../org/apache/doris/analysis/FloatLiteral.java | 19 ++- .../org/apache/doris/analysis/LiteralExpr.java | 19 +++ .../java/org/apache/doris/analysis/MapLiteral.java | 26 +++- .../org/apache/doris/analysis/StructLiteral.java | 15 +- .../apache/doris/analysis/ArrayLiteralTest.java | 80 ++++++++++ .../org/apache/doris/analysis/MapLiteralTest.java | 170 +++++++++++++++++++++ .../apache/doris/analysis/StructLiteralTest.java | 99 ++++++++++++ 11 files changed, 461 insertions(+), 6 deletions(-) diff --git a/fe/fe-common/src/main/java/org/apache/doris/catalog/Type.java b/fe/fe-common/src/main/java/org/apache/doris/catalog/Type.java index a1d3b7f8338..ea10972faa2 100644 --- a/fe/fe-common/src/main/java/org/apache/doris/catalog/Type.java +++ b/fe/fe-common/src/main/java/org/apache/doris/catalog/Type.java @@ -187,6 +187,8 @@ public abstract class Type { arraySubTypes.add(FLOAT); arraySubTypes.add(DOUBLE); arraySubTypes.add(DECIMALV2); + arraySubTypes.add(TIME); + arraySubTypes.add(TIMEV2); arraySubTypes.add(DATE); arraySubTypes.add(DATETIME); arraySubTypes.add(DATEV2); @@ -197,6 +199,10 @@ public abstract class Type { arraySubTypes.add(DECIMAL32); arraySubTypes.add(DECIMAL64); arraySubTypes.add(DECIMAL128); + arraySubTypes.add(NULL); + arraySubTypes.add(ARRAY); + arraySubTypes.add(MAP); + arraySubTypes.add(STRUCT); mapSubTypes = Lists.newArrayList(); mapSubTypes.add(BOOLEAN); @@ -207,6 +213,8 @@ public abstract class Type { mapSubTypes.add(DECIMAL32); // same DEFAULT_DECIMALV3 mapSubTypes.add(DECIMAL64); mapSubTypes.add(DECIMAL128); + mapSubTypes.add(TIME); + mapSubTypes.add(TIMEV2); mapSubTypes.add(DATE); mapSubTypes.add(DATETIME); mapSubTypes.add(DATEV2); @@ -215,6 +223,9 @@ public abstract class Type { mapSubTypes.add(VARCHAR); mapSubTypes.add(STRING); mapSubTypes.add(NULL); + mapSubTypes.add(ARRAY); + mapSubTypes.add(MAP); + mapSubTypes.add(STRUCT); structSubTypes = Lists.newArrayList(); structSubTypes.add(BOOLEAN); @@ -225,6 +236,8 @@ public abstract class Type { structSubTypes.add(DECIMAL32); // same DEFAULT_DECIMALV3 structSubTypes.add(DECIMAL64); structSubTypes.add(DECIMAL128); + structSubTypes.add(TIME); + structSubTypes.add(TIMEV2); structSubTypes.add(DATE); structSubTypes.add(DATETIME); structSubTypes.add(DATEV2); @@ -232,6 +245,10 @@ public abstract class Type { structSubTypes.add(CHAR); structSubTypes.add(VARCHAR); structSubTypes.add(STRING); + structSubTypes.add(NULL); + structSubTypes.add(ARRAY); + structSubTypes.add(MAP); + structSubTypes.add(STRUCT); } public static final Set<Class> DATE_SUPPORTED_JAVA_TYPE = Sets.newHashSet(LocalDate.class, java.util.Date.class, 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 66145cb5960..53142aea7d6 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 @@ -44,6 +44,9 @@ public class ArrayLiteral extends LiteralExpr { Type itemType = Type.NULL; boolean containsNull = true; for (LiteralExpr expr : exprs) { + if (!ArrayType.ARRAY.supportSubType(expr.getType())) { + throw new AnalysisException("Invalid item type in Array, not support " + expr.getType()); + } if (itemType == Type.NULL) { itemType = expr.getType(); } else { @@ -122,6 +125,16 @@ public class ArrayLiteral extends LiteralExpr { return "[" + StringUtils.join(list, ", ") + "]"; } + @Override + public String getStringValueInFe() { + List<String> list = new ArrayList<>(children.size()); + children.forEach(v -> { + // we should use type to decide we output array is suitable for json format + list.add(getStringLiteralForComplexType(v)); + }); + 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 0d781bff7b8..1fb14027a5c 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 @@ -255,6 +255,11 @@ public class DecimalLiteral extends LiteralExpr { return value.toString(); } + @Override + public String getStringValueInFe() { + return value.toPlainString(); + } + @Override public String getStringValueForArray() { 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 73a9e3b0478..bc463611a16 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 @@ -2210,6 +2210,10 @@ public abstract class Expr extends TreeNode<Expr> 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 c87505b22d2..b95b3860aa5 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 bde041aeefa..2be4ec3081c 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 @@ -101,6 +101,21 @@ public abstract class LiteralExpr extends Expr implements Comparable<LiteralExpr return literalExpr; } + + public static String getStringLiteralForComplexType(Expr v) { + if (!(v instanceof NullLiteral) && v.getType().isScalarType() + && (Type.getNumericTypes().contains((ScalarType) v.getActualScalarType(v.getType())) + || v.getType() == Type.BOOLEAN)) { + return v.getStringValueInFe(); + } else if (v.getType().isComplexType()) { + // these type should also call getStringValueInFe which should handle special case for itself + return v.getStringValueInFe(); + } else { + return v.getStringValueForArray(); + } + } + + /** * Init LiteralExpr's Type information * only use in rewrite alias function @@ -226,6 +241,10 @@ public abstract class LiteralExpr extends Expr implements Comparable<LiteralExpr @Override public abstract String getStringValue(); + public String getStringValueInFe() { + return getStringValue(); + } + @Override public abstract String getStringValueForArray(); diff --git a/fe/fe-core/src/main/java/org/apache/doris/analysis/MapLiteral.java b/fe/fe-core/src/main/java/org/apache/doris/analysis/MapLiteral.java index 62aead25e24..c7438709229 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/analysis/MapLiteral.java +++ b/fe/fe-core/src/main/java/org/apache/doris/analysis/MapLiteral.java @@ -53,9 +53,12 @@ public class MapLiteral extends LiteralExpr { // 1. limit key type with map-key support // 2. check type can be assigment for cast for (int idx = 0; idx < exprs.length && idx + 1 < exprs.length; idx += 2) { - if (!MapType.MAP.supportSubType(exprs[idx].getType())) { + if (exprs[idx].getType().isComplexType() || !MapType.MAP.supportSubType(exprs[idx].getType())) { throw new AnalysisException("Invalid key type in Map, not support " + exprs[idx].getType()); } + if (!MapType.MAP.supportSubType(exprs[idx + 1].getType())) { + throw new AnalysisException("Invalid value type in Map, not support " + exprs[idx].getType()); + } keyType = Type.getAssignmentCompatibleType(keyType, exprs[idx].getType(), true); valueType = Type.getAssignmentCompatibleType(valueType, exprs[idx + 1].getType(), true); } @@ -147,7 +150,26 @@ public class MapLiteral extends LiteralExpr { @Override public String getStringValueForArray() { - return null; + List<String> list = new ArrayList<>(children.size()); + for (int i = 0; i < children.size() && i + 1 < children.size(); i += 2) { + list.add(children.get(i).getStringValueForArray() + ":" + children.get(i + 1).getStringValueForArray()); + } + return "{" + StringUtils.join(list, ", ") + "}"; + } + + @Override + public String getStringValueInFe() { + List<String> list = new ArrayList<>(children.size()); + for (int i = 0; i < children.size() && i + 1 < children.size(); i += 2) { + // we should use type to decide we output array is suitable for json format + if (children.get(i).getType().isComplexType()) { + // map key type do not support complex type + throw new UnsupportedOperationException("Unsupport key type for MAP: " + children.get(i).getType()); + } + list.add(children.get(i).getStringValueForArray() + + ":" + getStringLiteralForComplexType(children.get(i + 1))); + } + return "{" + StringUtils.join(list, ", ") + "}"; } @Override diff --git a/fe/fe-core/src/main/java/org/apache/doris/analysis/StructLiteral.java b/fe/fe-core/src/main/java/org/apache/doris/analysis/StructLiteral.java index af87fcf6d2b..7720cd447a7 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/analysis/StructLiteral.java +++ b/fe/fe-core/src/main/java/org/apache/doris/analysis/StructLiteral.java @@ -47,8 +47,8 @@ public class StructLiteral extends LiteralExpr { type = new StructType(); children = new ArrayList<>(); for (LiteralExpr expr : exprs) { - if (!expr.getType().isNull() && !type.supportSubType(expr.getType())) { - throw new AnalysisException("Invalid element type in STRUCT."); + if (!StructType.STRUCT.supportSubType(expr.getType())) { + throw new AnalysisException("Invalid element type in STRUCT: " + expr.getType()); } ((StructType) type).addField(new StructField(expr.getType())); children.add(expr); @@ -82,7 +82,16 @@ public class StructLiteral extends LiteralExpr { @Override public String getStringValueForArray() { - return null; + List<String> list = new ArrayList<>(children.size()); + children.forEach(v -> list.add(v.getStringValueForArray())); + return "{" + StringUtils.join(list, ", ") + "}"; + } + + @Override + public String getStringValueInFe() { + List<String> list = new ArrayList<>(children.size()); + children.forEach(v -> list.add(getStringLiteralForComplexType(v))); + return "{" + StringUtils.join(list, ", ") + "}"; } @Override 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 53b9ede98d0..87c23ea4089 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 @@ -61,5 +61,85 @@ public class ArrayLiteralTest { ArrayLiteral arrayLiteral9 = new ArrayLiteral(); Assert.assertEquals("[]", arrayLiteral9.getStringValueForArray()); + + ArrayLiteral arrayLiteral = new ArrayLiteral(intLiteral1, floatLiteral); + MapLiteral mapLiteral = new MapLiteral(intLiteral1, floatLiteral); + StructLiteral structLiteral = new StructLiteral(intLiteral1, floatLiteral, dateLiteral); + ArrayLiteral arrayLiteral10 = new ArrayLiteral(arrayLiteral, arrayLiteral); + Assert.assertEquals("[[\"1\", \"2.15\"], [\"1\", \"2.15\"]]", arrayLiteral10.getStringValueForArray()); + ArrayLiteral arrayLiteral11 = new ArrayLiteral(mapLiteral); + Assert.assertEquals("[{\"1\":\"2.15\"}]", arrayLiteral11.getStringValueForArray()); + ArrayLiteral arrayLiteral12 = new ArrayLiteral(structLiteral); + Assert.assertEquals("[{\"1\", \"2.15\", \"2022-10-10\"}]", arrayLiteral12.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()); + + ArrayLiteral arrayLiteral = new ArrayLiteral(intLiteral1, floatLiteral); + MapLiteral mapLiteral = new MapLiteral(intLiteral1, floatLiteral); + StructLiteral structLiteral = new StructLiteral(intLiteral1, floatLiteral, dateLiteral); + ArrayLiteral arrayLiteral13 = new ArrayLiteral(arrayLiteral, arrayLiteral); + Assert.assertEquals("[[\"1\", \"2.15\"], [\"1\", \"2.15\"]]", arrayLiteral13.getStringValueForArray()); + ArrayLiteral arrayLiteral14 = new ArrayLiteral(mapLiteral); + Assert.assertEquals("[{\"1\":\"2.15\"}]", arrayLiteral14.getStringValueForArray()); + ArrayLiteral arrayLiteral15 = new ArrayLiteral(structLiteral); + Assert.assertEquals("[{\"1\", \"2.15\", \"2022-10-10\"}]", arrayLiteral15.getStringValueForArray()); + } } diff --git a/fe/fe-core/src/test/java/org/apache/doris/analysis/MapLiteralTest.java b/fe/fe-core/src/test/java/org/apache/doris/analysis/MapLiteralTest.java new file mode 100644 index 00000000000..0ab4fbcbcaa --- /dev/null +++ b/fe/fe-core/src/test/java/org/apache/doris/analysis/MapLiteralTest.java @@ -0,0 +1,170 @@ +// 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.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; + +public class MapLiteralTest { + static IntLiteral intLiteral1; + static FloatLiteral floatLiteral; + static FloatLiteral floatLiteral1; + static BoolLiteral boolLiteral; + static StringLiteral stringLiteral; + static LargeIntLiteral largeIntLiteral; + static NullLiteral nullLiteral; + static DateLiteral dateLiteral; + static DateLiteral datetimeLiteral; + static DecimalLiteral decimalLiteral1; + static DecimalLiteral decimalLiteral2; + static ArrayLiteral arrayLiteral; + static MapLiteral mapLiteral; + static StructLiteral structLiteral; + + + @BeforeAll + public static void setUp() throws AnalysisException { + intLiteral1 = new IntLiteral(1); + floatLiteral = new FloatLiteral("2.15"); + floatLiteral1 = new FloatLiteral((double) (11 * 3600 + 22 * 60 + 33), + FloatLiteral.getDefaultTimeType(Type.TIME)); + boolLiteral = new BoolLiteral(true); + stringLiteral = new StringLiteral("shortstring"); + largeIntLiteral = new LargeIntLiteral("1000000000000000000000"); + nullLiteral = new NullLiteral(); + dateLiteral = new DateLiteral("2022-10-10", Type.DATE); + datetimeLiteral = new DateLiteral("2022-10-10 12:10:10", Type.DATETIME); + decimalLiteral1 = new DecimalLiteral("1.0"); + decimalLiteral2 = new DecimalLiteral("2"); + arrayLiteral = new ArrayLiteral(intLiteral1, floatLiteral); + mapLiteral = new MapLiteral(intLiteral1, floatLiteral); + structLiteral = new StructLiteral(intLiteral1, floatLiteral, decimalLiteral1, dateLiteral); + + } + + @Test + public void testGetStringValueForArray() throws AnalysisException { + MapLiteral mapLiteral1 = new MapLiteral(intLiteral1, floatLiteral); + Assert.assertEquals("{\"1\":\"2.15\"}", mapLiteral1.getStringValueForArray()); + MapLiteral mapLiteral2 = new MapLiteral(boolLiteral, stringLiteral); + Assert.assertEquals("{\"1\":\"shortstring\"}", mapLiteral2.getStringValueForArray()); + MapLiteral mapLiteral3 = new MapLiteral(largeIntLiteral, dateLiteral); + Assert.assertEquals("{\"1000000000000000000000\":\"2022-10-10\"}", mapLiteral3.getStringValueForArray()); + MapLiteral mapLiteral4 = new MapLiteral(nullLiteral, nullLiteral); + Assert.assertEquals("{null:null}", mapLiteral4.getStringValueForArray()); + MapLiteral mapLiteral5 = new MapLiteral(datetimeLiteral, dateLiteral); + Assert.assertEquals("{\"2022-10-10 12:10:10\":\"2022-10-10\"}", mapLiteral5.getStringValueForArray()); + + MapLiteral mapLiteral6 = new MapLiteral(); + Assert.assertEquals("{}", mapLiteral6.getStringValueForArray()); + + MapLiteral mapLiteral7 = new MapLiteral(nullLiteral, intLiteral1); + Assert.assertEquals("{null:\"1\"}", mapLiteral7.getStringValueForArray()); + MapLiteral mapLiteral8 = new MapLiteral(intLiteral1, nullLiteral); + Assert.assertEquals("{\"1\":null}", mapLiteral8.getStringValueForArray()); + + MapLiteral mapLiteral10 = new MapLiteral(intLiteral1, arrayLiteral); + Assert.assertEquals("{\"1\":[\"1\", \"2.15\"]}", mapLiteral10.getStringValueForArray()); + try { + new MapLiteral(arrayLiteral, floatLiteral); + } catch (Exception e) { + Assert.assertEquals("errCode = 2, " + + "detailMessage = Invalid key type in Map, not support ARRAY<DOUBLE>", e.getMessage()); + } + + MapLiteral mapLiteral11 = new MapLiteral(decimalLiteral1, mapLiteral); + Assert.assertEquals("{\"1.0\":{\"1\":\"2.15\"}}", mapLiteral11.getStringValueForArray()); + try { + new MapLiteral(mapLiteral, decimalLiteral1); + } catch (Exception e) { + Assert.assertEquals("errCode = 2, " + + "detailMessage = Invalid key type in Map, not support MAP<TINYINT,DOUBLE>", e.getMessage()); + } + + MapLiteral mapLiteral13 = new MapLiteral(stringLiteral, structLiteral); + Assert.assertEquals("{\"shortstring\":{\"1\", \"2.15\", \"1.0\", \"2022-10-10\"}}", + mapLiteral13.getStringValueForArray()); + try { + new MapLiteral(structLiteral, stringLiteral); + } catch (Exception e) { + Assert.assertEquals("errCode = 2, detailMessage = Invalid key type in Map, " + + "not support STRUCT<col:TINYINT,col:DOUBLE,col:DECIMALV3(2, 1),col:DATE>", e.getMessage()); + } + + } + + + @Test + public void testGetStringInFe() throws AnalysisException { + MapLiteral mapLiteral1 = new MapLiteral(intLiteral1, floatLiteral); + Assert.assertEquals("{\"1\":2.15}", mapLiteral1.getStringValueInFe()); + MapLiteral mapLiteral11 = new MapLiteral(intLiteral1, floatLiteral1); + Assert.assertEquals("{\"1\":\"11:22:33\"}", mapLiteral11.getStringValueInFe()); + MapLiteral mapLiteral2 = new MapLiteral(boolLiteral, stringLiteral); + Assert.assertEquals("{\"1\":\"shortstring\"}", mapLiteral2.getStringValueInFe()); + MapLiteral mapLiteral3 = new MapLiteral(largeIntLiteral, dateLiteral); + Assert.assertEquals("{\"1000000000000000000000\":\"2022-10-10\"}", mapLiteral3.getStringValueInFe()); + MapLiteral mapLiteral4 = new MapLiteral(floatLiteral1, nullLiteral); + Assert.assertEquals("{\"11:22:33\":null}", mapLiteral4.getStringValueInFe()); + MapLiteral mapLiteral5 = new MapLiteral(datetimeLiteral, dateLiteral); + Assert.assertEquals("{\"2022-10-10 12:10:10\":\"2022-10-10\"}", mapLiteral5.getStringValueInFe()); + MapLiteral mapLiteral6 = new MapLiteral(decimalLiteral1, decimalLiteral2); + Assert.assertEquals("{\"1.0\":2}", mapLiteral6.getStringValueInFe()); + + MapLiteral mapLiteral7 = new MapLiteral(); + Assert.assertEquals("{}", mapLiteral7.getStringValueInFe()); + MapLiteral mapLiteral8 = new MapLiteral(nullLiteral, intLiteral1); + Assert.assertEquals("{null:1}", mapLiteral8.getStringValueInFe()); + MapLiteral mapLiteral9 = new MapLiteral(intLiteral1, nullLiteral); + Assert.assertEquals("{\"1\":null}", mapLiteral9.getStringValueInFe()); + + MapLiteral mapLiteral10 = new MapLiteral(intLiteral1, arrayLiteral); + Assert.assertEquals("{\"1\":[\"1\", \"2.15\"]}", mapLiteral10.getStringValueForArray()); + try { + new MapLiteral(arrayLiteral, floatLiteral); + } catch (Exception e) { + Assert.assertEquals("errCode = 2, " + + "detailMessage = Invalid key type in Map, not support ARRAY<DOUBLE>", e.getMessage()); + } + + MapLiteral mapLiteral12 = new MapLiteral(decimalLiteral1, mapLiteral); + Assert.assertEquals("{\"1.0\":{\"1\":\"2.15\"}}", mapLiteral12.getStringValueForArray()); + try { + new MapLiteral(mapLiteral, decimalLiteral1); + } catch (Exception e) { + Assert.assertEquals("errCode = 2, " + + "detailMessage = Invalid key type in Map, not support MAP<TINYINT,DOUBLE>", e.getMessage()); + } + + MapLiteral mapLiteral13 = new MapLiteral(stringLiteral, structLiteral); + Assert.assertEquals("{\"shortstring\":{\"1\", \"2.15\", \"1.0\", \"2022-10-10\"}}", + mapLiteral13.getStringValueForArray()); + try { + new MapLiteral(structLiteral, stringLiteral); + } catch (Exception e) { + Assert.assertEquals("errCode = 2, " + + "detailMessage = Invalid key type in Map, " + + "not support STRUCT<col:TINYINT,col:DOUBLE,col:DECIMALV3(2, 1),col:DATE>", e.getMessage()); + } + + } +} diff --git a/fe/fe-core/src/test/java/org/apache/doris/analysis/StructLiteralTest.java b/fe/fe-core/src/test/java/org/apache/doris/analysis/StructLiteralTest.java new file mode 100644 index 00000000000..d844ef318f6 --- /dev/null +++ b/fe/fe-core/src/test/java/org/apache/doris/analysis/StructLiteralTest.java @@ -0,0 +1,99 @@ +// 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.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; + +public class StructLiteralTest { + static IntLiteral intLiteral1; + static FloatLiteral floatLiteral; + static FloatLiteral floatLiteral1; + static BoolLiteral boolLiteral; + static StringLiteral stringLiteral; + static LargeIntLiteral largeIntLiteral; + static NullLiteral nullLiteral; + static DateLiteral dateLiteral; + static DateLiteral datetimeLiteral; + static DecimalLiteral decimalLiteral1; + static DecimalLiteral decimalLiteral2; + static ArrayLiteral arrayLiteral; + static MapLiteral mapLiteral; + static StructLiteral structLiteral; + + @BeforeAll + public static void setUp() throws AnalysisException { + intLiteral1 = new IntLiteral(1); + floatLiteral = new FloatLiteral("2.15"); + floatLiteral1 = new FloatLiteral((double) (11 * 3600 + 22 * 60 + 33), + FloatLiteral.getDefaultTimeType(Type.TIME)); + boolLiteral = new BoolLiteral(true); + stringLiteral = new StringLiteral("shortstring"); + largeIntLiteral = new LargeIntLiteral("1000000000000000000000"); + nullLiteral = new NullLiteral(); + dateLiteral = new DateLiteral("2022-10-10", Type.DATE); + datetimeLiteral = new DateLiteral("2022-10-10 12:10:10", Type.DATETIME); + decimalLiteral1 = new DecimalLiteral("1.0"); + decimalLiteral2 = new DecimalLiteral("2"); + arrayLiteral = new ArrayLiteral(intLiteral1, floatLiteral); + mapLiteral = new MapLiteral(intLiteral1, floatLiteral); + structLiteral = new StructLiteral(intLiteral1, floatLiteral, decimalLiteral1, dateLiteral); + + } + + @Test + public void testGetStringValueForArray() throws AnalysisException { + StructLiteral structLiteral1 = new StructLiteral(intLiteral1, floatLiteral, floatLiteral1, boolLiteral, + stringLiteral, largeIntLiteral, decimalLiteral1, decimalLiteral2, dateLiteral, + datetimeLiteral); + Assert.assertEquals("{\"1\", \"2.15\", \"11:22:33\", \"1\", \"shortstring\", " + + "\"1000000000000000000000\", \"1.0\", \"2\", \"2022-10-10\", \"2022-10-10 12:10:10\"}", + structLiteral1.getStringValueForArray()); + StructLiteral structLiteral2 = new StructLiteral(arrayLiteral, mapLiteral, structLiteral); + Assert.assertEquals("{[\"1\", \"2.15\"], {\"1\":\"2.15\"}, {\"1\", \"2.15\", \"1.0\", \"2022-10-10\"}}", + structLiteral2.getStringValueForArray()); + StructLiteral structLiteral3 = new StructLiteral(); + Assert.assertEquals("{}", structLiteral3.getStringValueForArray()); + + StructLiteral nullStruct = new StructLiteral(nullLiteral, intLiteral1); + Assert.assertEquals("{null, \"1\"}", nullStruct.getStringValueForArray()); + + } + + + @Test + public void testGetStringInFe() throws AnalysisException { + StructLiteral structLiteral1 = new StructLiteral(intLiteral1, floatLiteral, floatLiteral1, boolLiteral, + stringLiteral, largeIntLiteral, decimalLiteral1, decimalLiteral2, dateLiteral, datetimeLiteral); + Assert.assertEquals("{1, 2.15, \"11:22:33\", 1, \"shortstring\", 1000000000000000000000, 1.0, 2, " + + "\"2022-10-10\", \"2022-10-10 12:10:10\"}", + structLiteral1.getStringValueInFe()); + StructLiteral structLiteral2 = new StructLiteral(arrayLiteral, mapLiteral, structLiteral); + Assert.assertEquals("{[1.0, 2.15], {\"1\":2.15}, {1, 2.15, 1.0, \"2022-10-10\"}}", + structLiteral2.getStringValueInFe()); + StructLiteral structLiteral3 = new StructLiteral(); + Assert.assertEquals("{}", structLiteral3.getStringValueInFe()); + + StructLiteral nullStruct = new StructLiteral(nullLiteral, intLiteral1); + Assert.assertEquals("{null, 1}", nullStruct.getStringValueInFe()); + } +} --------------------------------------------------------------------- To unsubscribe, e-mail: commits-unsubscr...@doris.apache.org For additional commands, e-mail: commits-h...@doris.apache.org