From 97bd85392baa4f2190bda9eecb1c11019b6d67f7 Mon Sep 17 00:00:00 2001 From: zombee0 Date: Tue, 6 Dec 2022 00:00:47 +0800 Subject: [PATCH] support structType matchesType (#14592) --- .../com/starrocks/catalog/StructType.java | 27 +++++++ .../starrocks/sql/plan/StructTypeTest.java | 73 +++++++++++++++++++ 2 files changed, 100 insertions(+) diff --git a/fe/fe-core/src/main/java/com/starrocks/catalog/StructType.java b/fe/fe-core/src/main/java/com/starrocks/catalog/StructType.java index ae4f6c0c72b..60b3d70a87e 100644 --- a/fe/fe-core/src/main/java/com/starrocks/catalog/StructType.java +++ b/fe/fe-core/src/main/java/com/starrocks/catalog/StructType.java @@ -37,6 +37,7 @@ import org.apache.logging.log4j.Logger; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; +import java.util.Map; /** * Describes a STRUCT type. STRUCT types have a list of named struct fields. @@ -82,6 +83,32 @@ public class StructType extends Type { return size; } + @Override + public boolean matchesType(Type t) { + if (t.isPseudoType()) { + return t.matchesType(this); + } + if (!t.isStructType()) { + return false; + } + + if (((StructType) t).getFields().size() != fields.size()) { + return false; + } + + for (Map.Entry field : fieldMap.entrySet()) { + StructField tField = ((StructType) t).getField(field.getValue().getName()); + if (tField == null) { + return false; + } + if (!tField.getType().matchesType(field.getValue().getType())) { + return false; + } + } + + return true; + } + @Override public String toSql(int depth) { if (depth >= MAX_NESTING_DEPTH) { diff --git a/fe/fe-core/src/test/java/com/starrocks/sql/plan/StructTypeTest.java b/fe/fe-core/src/test/java/com/starrocks/sql/plan/StructTypeTest.java index 444be11c686..b26c965443d 100644 --- a/fe/fe-core/src/test/java/com/starrocks/sql/plan/StructTypeTest.java +++ b/fe/fe-core/src/test/java/com/starrocks/sql/plan/StructTypeTest.java @@ -2,6 +2,14 @@ package com.starrocks.sql.plan; +import com.google.common.collect.Lists; +import com.starrocks.catalog.AnyMapType; +import com.starrocks.catalog.MapType; +import com.starrocks.catalog.PrimitiveType; +import com.starrocks.catalog.ScalarType; +import com.starrocks.catalog.StructField; +import com.starrocks.catalog.StructType; +import com.starrocks.catalog.Type; import com.starrocks.utframe.StarRocksAssert; import org.junit.Assert; import org.junit.BeforeClass; @@ -41,4 +49,69 @@ public class StructTypeTest extends PlanTestBase { " | : 3: c2.b\n" + " | ")); } + + @Test + public void testStructMatchType() throws Exception { + // "struct>" + StructType c1 = new StructType(Lists.newArrayList( + new StructField("c1", ScalarType.createType(PrimitiveType.INT)), + new StructField("cc1", ScalarType.createDefaultExternalTableString()) + )); + StructType root = new StructType(Lists.newArrayList( + new StructField("struct_test", ScalarType.createType(PrimitiveType.INT)), + new StructField("c1", c1) + )); + + // PseudoType MapType + Type t = new AnyMapType(); + Assert.assertFalse(root.matchesType(t)); + + // MapType + Type keyType = ScalarType.createType(PrimitiveType.INT); + Type valueType = ScalarType.createCharType(10); + Type mapType = new MapType(keyType, valueType); + + Assert.assertFalse(root.matchesType(mapType)); + + // Different fields length + StructType c = new StructType(Lists.newArrayList( + new StructField("c1", ScalarType.createType(PrimitiveType.INT)))); + Assert.assertFalse(root.matchesType(c)); + + // Different field name + StructType diffName = new StructType(Lists.newArrayList( + new StructField("st", ScalarType.createType(PrimitiveType.INT)), + new StructField("cc", c1) + )); + Assert.assertFalse(root.matchesType(diffName)); + + // Different field type + StructType diffType = new StructType(Lists.newArrayList( + new StructField("struct_test", ScalarType.createType(PrimitiveType.INT)), + new StructField("c1", ScalarType.createType(PrimitiveType.INT)) + )); + Assert.assertFalse(root.matchesType(diffType)); + + // matched + StructType mc1 = new StructType(Lists.newArrayList( + new StructField("c1", ScalarType.createType(PrimitiveType.INT)), + new StructField("cc1", ScalarType.createDefaultExternalTableString()) + )); + StructType matched = new StructType(Lists.newArrayList( + new StructField("struct_test", ScalarType.createType(PrimitiveType.INT)), + new StructField("c1", mc1) + )); + Assert.assertTrue(root.matchesType(matched)); + + // matched with different subfield order + StructType mc2 = new StructType(Lists.newArrayList( + new StructField("cc1", ScalarType.createDefaultExternalTableString()), + new StructField("c1", ScalarType.createType(PrimitiveType.INT)) + )); + StructType matchedDiffOrder = new StructType(Lists.newArrayList( + new StructField("c1", mc2), + new StructField("struct_test", ScalarType.createType(PrimitiveType.INT)) + )); + Assert.assertTrue(root.matchesType(matchedDiffOrder)); + } }