[Improve](complex-type) Support Count(complexType) (#17868)

Support count function for ARRAY/MAP/STRUCT type
This commit is contained in:
amory
2023-03-30 15:43:32 +08:00
committed by GitHub
parent e3bd812887
commit ea41d94582
27 changed files with 175 additions and 86 deletions

View File

@ -699,7 +699,7 @@ public class FunctionCallExpr extends Expr {
}
for (Expr child : children) {
if (child.type.isOnlyMetricType()) {
if (child.type.isOnlyMetricType() && !child.type.isComplexType()) {
throw new AnalysisException(Type.OnlyMetricTypeErrorMsg);
}
}

View File

@ -24,8 +24,6 @@ import org.apache.doris.catalog.Function;
import org.apache.doris.catalog.Function.NullableMode;
import org.apache.doris.catalog.FunctionSet;
import org.apache.doris.catalog.ScalarFunction;
import org.apache.doris.catalog.StructField;
import org.apache.doris.catalog.StructType;
import org.apache.doris.catalog.Type;
import org.apache.doris.common.AnalysisException;
import org.apache.doris.thrift.TExprNode;
@ -62,7 +60,7 @@ public class IsNullPredicate extends Predicate {
isNotNullSymbol, Lists.newArrayList(t), Type.BOOLEAN, NullableMode.ALWAYS_NOT_NULLABLE));
// for array type
for (Type complexType : Lists.newArrayList(Type.ARRAY, Type.MAP)) {
for (Type complexType : Lists.newArrayList(Type.ARRAY, Type.MAP, Type.GENERIC_STRUCT)) {
functionSet.addBuiltinBothScalaAndVectorized(ScalarFunction.createBuiltinOperator(IS_NULL, isNullSymbol,
Lists.newArrayList(complexType), Type.BOOLEAN, NullableMode.ALWAYS_NOT_NULLABLE));
@ -71,12 +69,6 @@ public class IsNullPredicate extends Predicate {
NullableMode.ALWAYS_NOT_NULLABLE));
}
Type nullStruct = new StructType(Lists.newArrayList(new StructField("null_pred", Type.NULL)));
functionSet.addBuiltinBothScalaAndVectorized(ScalarFunction.createBuiltinOperator(IS_NULL, isNullSymbol,
Lists.newArrayList(nullStruct), Type.BOOLEAN, NullableMode.ALWAYS_NOT_NULLABLE));
functionSet.addBuiltinBothScalaAndVectorized(ScalarFunction.createBuiltinOperator(IS_NOT_NULL,
isNotNullSymbol, Lists.newArrayList(nullStruct), Type.BOOLEAN, NullableMode.ALWAYS_NOT_NULLABLE));
}
}

View File

@ -1564,6 +1564,27 @@ public class FunctionSet<T> {
prefix + "17count_star_removeEPN9doris_udf15FunctionContextEPNS1_9BigIntValE",
null, false, true, true, true));
// count(array/map/struct)
for (Type complexType : Lists.newArrayList(Type.ARRAY, Type.MAP, Type.GENERIC_STRUCT)) {
addBuiltin(AggregateFunction.createBuiltin(FunctionSet.COUNT,
Lists.newArrayList(complexType), Type.BIGINT, Type.BIGINT,
prefix + "18init_zero_not_nullIN9doris_udf9BigIntValEEEvPNS2_15FunctionContextEPT_",
prefix + "12count_updateEPN9doris_udf15FunctionContextERKNS1_6AnyValEPNS1_9BigIntValE",
prefix + "11count_mergeEPN9doris_udf15FunctionContextERKNS1_9BigIntValEPS4_",
null, null,
prefix + "12count_removeEPN9doris_udf15FunctionContextERKNS1_6AnyValEPNS1_9BigIntValE",
null, false, true, true, true));
addBuiltin(AggregateFunction.createBuiltin(FunctionSet.COUNT,
Lists.newArrayList(complexType), Type.BIGINT, Type.BIGINT,
prefix + "18init_zero_not_nullIN9doris_udf9BigIntValEEEvPNS2_15FunctionContextEPT_",
prefix + "12count_updateEPN9doris_udf15FunctionContextERKNS1_6AnyValEPNS1_9BigIntValE",
prefix + "11count_mergeEPN9doris_udf15FunctionContextERKNS1_9BigIntValEPS4_",
null, null,
prefix + "12count_removeEPN9doris_udf15FunctionContextERKNS1_6AnyValEPNS1_9BigIntValE",
null, false, true, true, true));
}
// windowFunnel
addBuiltin(AggregateFunction.createBuiltin(FunctionSet.WINDOW_FUNNEL,
Lists.newArrayList(Type.BIGINT, Type.STRING, Type.DATETIME, Type.BOOLEAN),

View File

@ -20,6 +20,7 @@ package org.apache.doris.analysis;
import org.apache.doris.common.Config;
import org.apache.doris.utframe.TestWithFeService;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
public class IsNullPredicateWithComplexTypeTest extends TestWithFeService {
@ -53,8 +54,19 @@ public class IsNullPredicateWithComplexTypeTest extends TestWithFeService {
String testStructIsNUll = "select * from test.complex where s is null";
String testMapIsNUll = "select * from test.complex where m is null";
String testArrayIsNUll = "select * from test.complex where a is null";
assertSQLPlanOrErrorMsgContains(testStructIsNUll, "");
assertSQLPlanOrErrorMsgContains(testMapIsNUll, "");
assertSQLPlanOrErrorMsgContains(testArrayIsNUll, "");
Assertions.assertNotNull(getSQLPlanner(testStructIsNUll));
Assertions.assertNotNull(getSQLPlanner(testMapIsNUll));
Assertions.assertNotNull(getSQLPlanner(testArrayIsNUll));
}
@Test
public void testCount() throws Exception {
String testStructIsNUll = "select count(s) from test.complex";
String testMapIsNUll = "select count(m) from test.complex";
String testArrayIsNUll = "select count(a) from test.complex";
Assertions.assertNotNull(getSQLPlanner(testStructIsNUll));
Assertions.assertNotNull(getSQLPlanner(testMapIsNUll));
Assertions.assertNotNull(getSQLPlanner(testArrayIsNUll));
}
}