From 6347bb1feb61229616cfb65590bc1d40b538a80f Mon Sep 17 00:00:00 2001 From: 924060929 Date: Fri, 5 Dec 2025 16:39:29 +0800 Subject: [PATCH 1/2] prune nested column through lateral view --- .../AccessPathExpressionCollector.java | 17 +- .../rewrite/AccessPathPlanCollector.java | 166 ++++++++++++++++++ .../rules/rewrite/SlotTypeReplacer.java | 6 + .../functions/generator/Explode.java | 11 +- .../generator/ExplodeJsonArrayDouble.java | 3 +- .../ExplodeJsonArrayDoubleOuter.java | 3 +- .../generator/ExplodeJsonArrayInt.java | 3 +- .../generator/ExplodeJsonArrayIntOuter.java | 3 +- .../generator/ExplodeJsonArrayJson.java | 3 +- .../generator/ExplodeJsonArrayJsonOuter.java | 3 +- .../generator/ExplodeJsonArrayString.java | 3 +- .../ExplodeJsonArrayStringOuter.java | 3 +- .../functions/generator/ExplodeMap.java | 6 +- .../functions/generator/ExplodeOuter.java | 10 +- .../functions/generator/ExplodeSplit.java | 3 +- .../generator/ExplodeSplitOuter.java | 3 +- .../functions/generator/PosExplode.java | 13 +- .../functions/generator/PosExplodeOuter.java | 12 +- .../expressions/literal/StructLiteral.java | 3 +- .../rules/rewrite/PruneNestedColumnTest.java | 141 +++++++++++++++ .../functions/generator/ExplodeOuterTest.java | 14 +- .../functions/generator/ExplodeTest.java | 12 +- .../generator/PosExplodeOuterTest.java | 10 +- .../functions/generator/PosExplodeTest.java | 8 +- 24 files changed, 392 insertions(+), 67 deletions(-) diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/rewrite/AccessPathExpressionCollector.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/rewrite/AccessPathExpressionCollector.java index 3ad75993e8799a..dcfcce4cf4ebd4 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/rewrite/AccessPathExpressionCollector.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/rewrite/AccessPathExpressionCollector.java @@ -449,9 +449,14 @@ public TAccessPathType getType() { public void setType(TAccessPathType type) { this.type = type; } + + public AccessPathBuilder getAccessPathBuilder() { + return accessPathBuilder; + } } - private static class AccessPathBuilder { + /** AccessPathBuilder */ + public static class AccessPathBuilder { private LinkedList accessPath; public AccessPathBuilder() { @@ -463,6 +468,16 @@ public AccessPathBuilder addPrefix(String prefix) { return this; } + public AccessPathBuilder addSuffix(String suffix) { + accessPath.addLast(suffix); + return this; + } + + public AccessPathBuilder addSuffix(List suffix) { + accessPath.addAll(suffix); + return this; + } + public AccessPathBuilder removePrefix() { accessPath.removeFirst(); return this; diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/rewrite/AccessPathPlanCollector.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/rewrite/AccessPathPlanCollector.java index ed253167b385c0..2625218baa64c8 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/rewrite/AccessPathPlanCollector.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/rewrite/AccessPathPlanCollector.java @@ -17,23 +17,35 @@ package org.apache.doris.nereids.rules.rewrite; +import org.apache.doris.analysis.AccessPathInfo; import org.apache.doris.nereids.StatementContext; import org.apache.doris.nereids.rules.rewrite.AccessPathExpressionCollector.CollectAccessPathResult; +import org.apache.doris.nereids.rules.rewrite.AccessPathExpressionCollector.CollectorContext; import org.apache.doris.nereids.trees.expressions.Alias; import org.apache.doris.nereids.trees.expressions.Expression; import org.apache.doris.nereids.trees.expressions.NamedExpression; import org.apache.doris.nereids.trees.expressions.Slot; +import org.apache.doris.nereids.trees.expressions.functions.Function; +import org.apache.doris.nereids.trees.expressions.functions.generator.Explode; +import org.apache.doris.nereids.trees.expressions.functions.generator.ExplodeMap; +import org.apache.doris.nereids.trees.expressions.functions.generator.ExplodeMapOuter; +import org.apache.doris.nereids.trees.expressions.functions.generator.ExplodeOuter; +import org.apache.doris.nereids.trees.expressions.functions.generator.PosExplode; +import org.apache.doris.nereids.trees.expressions.functions.generator.PosExplodeOuter; +import org.apache.doris.nereids.trees.expressions.literal.StructLiteral; import org.apache.doris.nereids.trees.plans.Plan; import org.apache.doris.nereids.trees.plans.logical.LogicalCTEAnchor; import org.apache.doris.nereids.trees.plans.logical.LogicalCTEConsumer; import org.apache.doris.nereids.trees.plans.logical.LogicalCTEProducer; import org.apache.doris.nereids.trees.plans.logical.LogicalFileScan; import org.apache.doris.nereids.trees.plans.logical.LogicalFilter; +import org.apache.doris.nereids.trees.plans.logical.LogicalGenerate; import org.apache.doris.nereids.trees.plans.logical.LogicalOlapScan; import org.apache.doris.nereids.trees.plans.logical.LogicalProject; import org.apache.doris.nereids.trees.plans.logical.LogicalTVFRelation; import org.apache.doris.nereids.trees.plans.logical.LogicalUnion; import org.apache.doris.nereids.trees.plans.visitor.DefaultPlanVisitor; +import org.apache.doris.nereids.types.DataType; import org.apache.doris.nereids.types.NestedColumnPrunable; import com.google.common.collect.LinkedHashMultimap; @@ -45,6 +57,8 @@ import java.util.List; import java.util.Map; import java.util.Map.Entry; +import java.util.Set; +import java.util.TreeSet; /** AccessPathPlanCollector */ public class AccessPathPlanCollector extends DefaultPlanVisitor { @@ -56,6 +70,145 @@ public Map> collect(Plan root, StatementCont return scanSlotToAccessPaths; } + @Override + public Void visitLogicalGenerate(LogicalGenerate generate, StatementContext context) { + List generators = generate.getGenerators(); + List output = generate.getGeneratorOutput(); + + AccessPathExpressionCollector exprCollector + = new AccessPathExpressionCollector(context, allSlotToAccessPaths, false); + for (int i = 0; i < output.size(); i++) { + Slot generatorOutput = output.get(i); + Function function = generators.get(i); + Collection accessPaths = allSlotToAccessPaths.get( + generatorOutput.getExprId().asInt()); + if (function instanceof Explode || function instanceof ExplodeOuter) { + if (accessPaths.isEmpty()) { + // use the whole column + for (Expression child : function.children()) { + exprCollector.collect(child); + } + } else { + for (CollectAccessPathResult accessPath : accessPaths) { + List path = accessPath.getPath(); + if (function.arity() == 1) { + // $c$1.VALUES.b + CollectorContext argumentContext = new CollectorContext(context, false); + argumentContext.setType(accessPath.getType()); + argumentContext.getAccessPathBuilder() + .addSuffix(AccessPathInfo.ACCESS_ALL) + .addSuffix(path.subList(1, path.size())); + function.child(0).accept(exprCollector, argumentContext); + continue; + } else if (path.size() >= 2) { + // $c$1.col1.VALUES.b will be extract 'col1' + String colName = path.get(1); + // extract '1' in 'col1' + int colIndex = Integer.parseInt(colName.substring(StructLiteral.COL_PREFIX.length())) - 1; + CollectorContext argumentContext = new CollectorContext(context, false); + argumentContext.setType(accessPath.getType()); + argumentContext.getAccessPathBuilder() + .addSuffix(AccessPathInfo.ACCESS_ALL) + .addSuffix(path.subList(2, path.size())); + function.child(colIndex).accept(exprCollector, argumentContext); + continue; + } + // use the whole column + for (Expression child : function.children()) { + exprCollector.collect(child); + } + } + } + } else if (function instanceof ExplodeMap || function instanceof ExplodeMapOuter) { + if (accessPaths.isEmpty()) { + // use the whole column + for (Expression child : function.children()) { + exprCollector.collect(child); + } + } else { + for (CollectAccessPathResult accessPath : accessPaths) { + List path = accessPath.getPath(); + if (path.size() >= 2) { + if (path.get(1).equalsIgnoreCase(StructLiteral.COL_PREFIX + "1")) { + // key + for (Expression child : function.children()) { + CollectorContext argumentContext = new CollectorContext(context, false); + argumentContext.setType(accessPath.getType()); + argumentContext.getAccessPathBuilder() + .addSuffix(AccessPathInfo.ACCESS_MAP_KEYS) + .addSuffix(path.subList(2, path.size())); + child.accept(exprCollector, argumentContext); + } + continue; + } else if (path.get(1).equalsIgnoreCase(StructLiteral.COL_PREFIX + "2")) { + // value + for (Expression child : function.children()) { + CollectorContext argumentContext = new CollectorContext(context, false); + argumentContext.setType(accessPath.getType()); + argumentContext.getAccessPathBuilder() + .addSuffix(AccessPathInfo.ACCESS_MAP_VALUES) + .addSuffix(path.subList(2, path.size())); + child.accept(exprCollector, argumentContext); + } + continue; + } + } + // use the whole column + exprCollector.collect(function.child(0)); + } + } + } else if (function instanceof PosExplode || function instanceof PosExplodeOuter) { + if (accessPaths.isEmpty()) { + // use the whole column + for (Expression child : function.children()) { + exprCollector.collect(child); + } + } else { + boolean useWholeItem = false; + Set prunedChildIndex = new TreeSet<>(); + for (CollectAccessPathResult accessPath : accessPaths) { + List path = accessPath.getPath(); + if (path.size() >= 2) { + // $c$1.col1.VALUES.b will be extract 'col1' + String colName = path.get(1); + if (colName.startsWith(StructLiteral.COL_PREFIX)) { + // $c$1.col1.VALUES.b will be extract 'col1' + // extract '1' in 'col1' + int colIndex + = Integer.parseInt(colName.substring(StructLiteral.COL_PREFIX.length())) - 1; + CollectorContext argumentContext = new CollectorContext(context, false); + argumentContext.setType(accessPath.getType()); + argumentContext.getAccessPathBuilder() + .addSuffix(AccessPathInfo.ACCESS_ALL) + .addSuffix(path.subList(2, path.size())); + function.child(colIndex).accept(exprCollector, argumentContext); + prunedChildIndex.add(colIndex); + } + } else { + useWholeItem = true; + break; + } + } + if (useWholeItem) { + // use the whole column + for (Expression child : function.children()) { + exprCollector.collect(child); + } + } else { + for (int j = 0; j < function.arity(); j++) { + if (!prunedChildIndex.contains(j)) { + exprCollector.collect(function.child(j)); + } + } + } + } + } else { + exprCollector.collect(function); + } + } + return generate.child().accept(this, context); + } + @Override public Void visitLogicalProject(LogicalProject project, StatementContext context) { AccessPathExpressionCollector exprCollector @@ -198,4 +351,17 @@ private void collectByExpressions(Plan plan, StatementContext context, boolean b exprCollector.collect(expression); } } + + private boolean argumentsHasSameType(Expression function) { + DataType firstType = null; + for (Expression argument : function.getArguments()) { + DataType argumentType = argument.getDataType(); + if (firstType == null) { + firstType = argumentType; + } else if (!firstType.equals(argumentType)) { + return false; + } + } + return true; + } } diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/rewrite/SlotTypeReplacer.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/rewrite/SlotTypeReplacer.java index 99ccdaf330914d..7f34fe90f7ea9c 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/rewrite/SlotTypeReplacer.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/rewrite/SlotTypeReplacer.java @@ -325,6 +325,12 @@ public Plan visitLogicalGenerate(LogicalGenerate generate, Void Pair> replacedGenerators = replaceExpressions(generate.getGenerators(), false, false); + for (int i = 0; i < replacedGenerators.second.size(); i++) { + DataType dataType = replacedGenerators.second.get(i).getDataType(); + replacedDataTypes.put(generate.getGeneratorOutput().get(i).getExprId().asInt(), + new AccessPathInfo(dataType, null, null) + ); + } Pair> replacedGeneratorOutput = replaceExpressions(generate.getGeneratorOutput(), false, false); if (replacedGenerators.first || replacedGeneratorOutput.first) { diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/generator/Explode.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/generator/Explode.java index c8e23b2a0b7a1d..c4a9901ed15431 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/generator/Explode.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/generator/Explode.java @@ -23,12 +23,14 @@ import org.apache.doris.nereids.trees.expressions.functions.ComputePrecision; import org.apache.doris.nereids.trees.expressions.functions.CustomSignature; import org.apache.doris.nereids.trees.expressions.functions.SearchSignature; +import org.apache.doris.nereids.trees.expressions.literal.StructLiteral; import org.apache.doris.nereids.trees.expressions.visitor.ExpressionVisitor; import org.apache.doris.nereids.types.ArrayType; import org.apache.doris.nereids.types.DataType; import org.apache.doris.nereids.types.NullType; import org.apache.doris.nereids.types.StructField; import org.apache.doris.nereids.types.StructType; +import org.apache.doris.nereids.util.ExpressionUtils; import com.google.common.base.Preconditions; import com.google.common.collect.ImmutableList; @@ -42,12 +44,11 @@ * where the first column contains 1, 2, 3, and the second column contains 4, 5, 6. */ public class Explode extends TableGeneratingFunction implements CustomSignature, ComputePrecision, AlwaysNullable { - /** * constructor with one or more argument. */ - public Explode(Expression[] args) { - super("explode", args); + public Explode(Expression arg, Expression... others) { + super("explode", ExpressionUtils.mergeArguments(arg, others)); } /** constructor for withChildren and reuse signature */ @@ -77,10 +78,10 @@ public FunctionSignature customSignature() { if (children.get(i).getDataType().isNullType()) { arguments.add(ArrayType.of(NullType.INSTANCE)); structFields.add( - new StructField("col" + (i + 1), NullType.INSTANCE, true, "")); + new StructField(StructLiteral.COL_PREFIX + (i + 1), NullType.INSTANCE, true, "")); } else if (children.get(i).getDataType().isArrayType()) { structFields.add( - new StructField("col" + (i + 1), + new StructField(StructLiteral.COL_PREFIX + (i + 1), ((ArrayType) (children.get(i)).getDataType()).getItemType(), true, "")); arguments.add(children.get(i).getDataType()); } else { diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/generator/ExplodeJsonArrayDouble.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/generator/ExplodeJsonArrayDouble.java index 6fb6dfb1c4ce6f..8f544dd483e2d8 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/generator/ExplodeJsonArrayDouble.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/generator/ExplodeJsonArrayDouble.java @@ -76,7 +76,6 @@ public R accept(ExpressionVisitor visitor, C context) { @Override public Expression rewriteWhenAnalyze() { - Expression[] args = {new Cast(children.get(0), ArrayType.of(DoubleType.INSTANCE))}; - return new Explode(args); + return new Explode(new Cast(children.get(0), ArrayType.of(DoubleType.INSTANCE))); } } diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/generator/ExplodeJsonArrayDoubleOuter.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/generator/ExplodeJsonArrayDoubleOuter.java index a9246a58b5accb..de7c7ac4707c35 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/generator/ExplodeJsonArrayDoubleOuter.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/generator/ExplodeJsonArrayDoubleOuter.java @@ -76,7 +76,6 @@ public R accept(ExpressionVisitor visitor, C context) { @Override public Expression rewriteWhenAnalyze() { - Expression[] args = {new Cast(children.get(0), ArrayType.of(DoubleType.INSTANCE))}; - return new ExplodeOuter(args); + return new ExplodeOuter(new Cast(children.get(0), ArrayType.of(DoubleType.INSTANCE))); } } diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/generator/ExplodeJsonArrayInt.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/generator/ExplodeJsonArrayInt.java index 367d3eca56891d..b19a18ed9a469d 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/generator/ExplodeJsonArrayInt.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/generator/ExplodeJsonArrayInt.java @@ -76,7 +76,6 @@ public R accept(ExpressionVisitor visitor, C context) { @Override public Expression rewriteWhenAnalyze() { - Expression[] args = {new Cast(children.get(0), ArrayType.of(BigIntType.INSTANCE))}; - return new Explode(args); + return new Explode(new Cast(children.get(0), ArrayType.of(BigIntType.INSTANCE))); } } diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/generator/ExplodeJsonArrayIntOuter.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/generator/ExplodeJsonArrayIntOuter.java index f31deb98a91369..e693114686da94 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/generator/ExplodeJsonArrayIntOuter.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/generator/ExplodeJsonArrayIntOuter.java @@ -76,7 +76,6 @@ public R accept(ExpressionVisitor visitor, C context) { @Override public Expression rewriteWhenAnalyze() { - Expression[] args = {new Cast(children.get(0), ArrayType.of(BigIntType.INSTANCE))}; - return new ExplodeOuter(args); + return new ExplodeOuter(new Cast(children.get(0), ArrayType.of(BigIntType.INSTANCE))); } } diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/generator/ExplodeJsonArrayJson.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/generator/ExplodeJsonArrayJson.java index f7d23f47c9239b..af94ab7f32b9b9 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/generator/ExplodeJsonArrayJson.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/generator/ExplodeJsonArrayJson.java @@ -75,7 +75,6 @@ public R accept(ExpressionVisitor visitor, C context) { @Override public Expression rewriteWhenAnalyze() { - Expression[] args = {new Cast(children.get(0), ArrayType.of(JsonType.INSTANCE))}; - return new Explode(args); + return new Explode(new Cast(children.get(0), ArrayType.of(JsonType.INSTANCE))); } } diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/generator/ExplodeJsonArrayJsonOuter.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/generator/ExplodeJsonArrayJsonOuter.java index 8922ab58282be9..5985e36c003e15 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/generator/ExplodeJsonArrayJsonOuter.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/generator/ExplodeJsonArrayJsonOuter.java @@ -75,7 +75,6 @@ public R accept(ExpressionVisitor visitor, C context) { @Override public Expression rewriteWhenAnalyze() { - Expression[] args = {new Cast(children.get(0), ArrayType.of(JsonType.INSTANCE))}; - return new ExplodeOuter(args); + return new ExplodeOuter(new Cast(children.get(0), ArrayType.of(JsonType.INSTANCE))); } } diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/generator/ExplodeJsonArrayString.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/generator/ExplodeJsonArrayString.java index d5bfc169aa8f11..77900d6d35988c 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/generator/ExplodeJsonArrayString.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/generator/ExplodeJsonArrayString.java @@ -76,7 +76,6 @@ public R accept(ExpressionVisitor visitor, C context) { @Override public Expression rewriteWhenAnalyze() { - Expression[] args = {new Cast(children.get(0), ArrayType.of(VarcharType.SYSTEM_DEFAULT))}; - return new Explode(args); + return new Explode(new Cast(children.get(0), ArrayType.of(VarcharType.SYSTEM_DEFAULT))); } } diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/generator/ExplodeJsonArrayStringOuter.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/generator/ExplodeJsonArrayStringOuter.java index b5498212e1dd1e..9728a375428a58 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/generator/ExplodeJsonArrayStringOuter.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/generator/ExplodeJsonArrayStringOuter.java @@ -76,7 +76,6 @@ public R accept(ExpressionVisitor visitor, C context) { @Override public Expression rewriteWhenAnalyze() { - Expression[] args = {new Cast(children.get(0), ArrayType.of(VarcharType.SYSTEM_DEFAULT))}; - return new ExplodeOuter(args); + return new ExplodeOuter(new Cast(children.get(0), ArrayType.of(VarcharType.SYSTEM_DEFAULT))); } } diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/generator/ExplodeMap.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/generator/ExplodeMap.java index f80677454049d0..68d9559e75ad92 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/generator/ExplodeMap.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/generator/ExplodeMap.java @@ -21,6 +21,7 @@ import org.apache.doris.nereids.exceptions.AnalysisException; import org.apache.doris.nereids.trees.expressions.Expression; import org.apache.doris.nereids.trees.expressions.functions.AlwaysNullable; +import org.apache.doris.nereids.trees.expressions.literal.StructLiteral; import org.apache.doris.nereids.trees.expressions.shape.UnaryExpression; import org.apache.doris.nereids.trees.expressions.visitor.ExpressionVisitor; import org.apache.doris.nereids.types.MapType; @@ -70,10 +71,11 @@ public void checkLegalityBeforeTypeCoercion() { @Override public List getSignatures() { + MapType dataType = (MapType) child().getDataType(); return ImmutableList.of( FunctionSignature.ret(new StructType(ImmutableList.of( - new StructField("col1", ((MapType) child().getDataType()).getKeyType(), true, ""), - new StructField("col2", ((MapType) child().getDataType()).getValueType(), true, "")))) + new StructField(StructLiteral.COL_PREFIX + "1", dataType.getKeyType(), true, ""), + new StructField(StructLiteral.COL_PREFIX + "2", dataType.getValueType(), true, "")))) .args(child().getDataType()) ); } diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/generator/ExplodeOuter.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/generator/ExplodeOuter.java index 4a26ea14fb6bbf..f3694c6b0c8d88 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/generator/ExplodeOuter.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/generator/ExplodeOuter.java @@ -23,12 +23,14 @@ import org.apache.doris.nereids.trees.expressions.functions.ComputePrecision; import org.apache.doris.nereids.trees.expressions.functions.CustomSignature; import org.apache.doris.nereids.trees.expressions.functions.SearchSignature; +import org.apache.doris.nereids.trees.expressions.literal.StructLiteral; import org.apache.doris.nereids.trees.expressions.visitor.ExpressionVisitor; import org.apache.doris.nereids.types.ArrayType; import org.apache.doris.nereids.types.DataType; import org.apache.doris.nereids.types.NullType; import org.apache.doris.nereids.types.StructField; import org.apache.doris.nereids.types.StructType; +import org.apache.doris.nereids.util.ExpressionUtils; import com.google.common.base.Preconditions; import com.google.common.collect.ImmutableList; @@ -46,8 +48,8 @@ public class ExplodeOuter extends TableGeneratingFunction implements CustomSigna /** * constructor with one or more argument. */ - public ExplodeOuter(Expression[] args) { - super("explode_outer", args); + public ExplodeOuter(Expression arg, Expression... others) { + super("explode_outer", ExpressionUtils.mergeArguments(arg, others)); } /** constructor for withChildren and reuse signature */ @@ -77,10 +79,10 @@ public FunctionSignature customSignature() { if (children.get(i).getDataType().isNullType()) { arguments.add(ArrayType.of(NullType.INSTANCE)); structFields.add( - new StructField("col" + (i + 1), NullType.INSTANCE, true, "")); + new StructField(StructLiteral.COL_PREFIX + (i + 1), NullType.INSTANCE, true, "")); } else if (children.get(i).getDataType().isArrayType()) { structFields.add( - new StructField("col" + (i + 1), + new StructField(StructLiteral.COL_PREFIX + (i + 1), ((ArrayType) (children.get(i)).getDataType()).getItemType(), true, "")); arguments.add(children.get(i).getDataType()); } else { diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/generator/ExplodeSplit.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/generator/ExplodeSplit.java index 87caf0f78f1cae..2c0cd5b20ad33c 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/generator/ExplodeSplit.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/generator/ExplodeSplit.java @@ -75,7 +75,6 @@ public R accept(ExpressionVisitor visitor, C context) { @Override public Expression rewriteWhenAnalyze() { - Expression[] args = {new SplitByString(children.get(0), children.get(1))}; - return new Explode(args); + return new Explode(new SplitByString(children.get(0), children.get(1))); } } diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/generator/ExplodeSplitOuter.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/generator/ExplodeSplitOuter.java index 7ecc54ca9ab0b9..a3066227ddf94e 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/generator/ExplodeSplitOuter.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/generator/ExplodeSplitOuter.java @@ -75,7 +75,6 @@ public R accept(ExpressionVisitor visitor, C context) { @Override public Expression rewriteWhenAnalyze() { - Expression[] args = {new SplitByString(children.get(0), children.get(1))}; - return new ExplodeOuter(args); + return new ExplodeOuter(new SplitByString(children.get(0), children.get(1))); } } diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/generator/PosExplode.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/generator/PosExplode.java index 8ff2de6f7bffba..b5091c09f1d6b2 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/generator/PosExplode.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/generator/PosExplode.java @@ -24,12 +24,14 @@ import org.apache.doris.nereids.trees.expressions.functions.ComputePrecision; import org.apache.doris.nereids.trees.expressions.functions.CustomSignature; import org.apache.doris.nereids.trees.expressions.functions.SearchSignature; +import org.apache.doris.nereids.trees.expressions.literal.StructLiteral; import org.apache.doris.nereids.trees.expressions.visitor.ExpressionVisitor; import org.apache.doris.nereids.types.ArrayType; import org.apache.doris.nereids.types.DataType; import org.apache.doris.nereids.types.IntegerType; import org.apache.doris.nereids.types.StructField; import org.apache.doris.nereids.types.StructType; +import org.apache.doris.nereids.util.ExpressionUtils; import com.google.common.base.Preconditions; import com.google.common.collect.ImmutableList; @@ -43,12 +45,13 @@ * value column: 'a', 'b', 'c' */ public class PosExplode extends TableGeneratingFunction implements CustomSignature, ComputePrecision, AlwaysNullable { + public static final String POS_COLUMN = "pos"; /** * constructor with one or more arguments. */ - public PosExplode(Expression[] args) { - super("posexplode", args); + public PosExplode(Expression arg, Expression... others) { + super("posexplode", ExpressionUtils.mergeArguments(arg, others)); } /** constructor for withChildren and reuse signature */ @@ -61,7 +64,7 @@ private PosExplode(GeneratorFunctionParams functionParams) { */ @Override public PosExplode withChildren(List children) { - Preconditions.checkArgument(children.size() == 1); + Preconditions.checkArgument(!children.isEmpty()); return new PosExplode(getFunctionParams(children)); } @@ -84,11 +87,11 @@ public FunctionSignature computePrecision(FunctionSignature signature) { public FunctionSignature customSignature() { List arguments = new ArrayList<>(); ImmutableList.Builder structFields = ImmutableList.builder(); - structFields.add(new StructField("pos", IntegerType.INSTANCE, false, "")); + structFields.add(new StructField(POS_COLUMN, IntegerType.INSTANCE, false, "")); for (int i = 0; i < children.size(); i++) { if (children.get(i).getDataType().isArrayType()) { structFields.add( - new StructField("col" + (i + 1), + new StructField(StructLiteral.COL_PREFIX + (i + 1), ((ArrayType) (children.get(i)).getDataType()).getItemType(), true, "")); arguments.add(children.get(i).getDataType()); } else { diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/generator/PosExplodeOuter.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/generator/PosExplodeOuter.java index c6e0deeef5fb75..c071f702f45247 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/generator/PosExplodeOuter.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/generator/PosExplodeOuter.java @@ -24,12 +24,14 @@ import org.apache.doris.nereids.trees.expressions.functions.ComputePrecision; import org.apache.doris.nereids.trees.expressions.functions.CustomSignature; import org.apache.doris.nereids.trees.expressions.functions.SearchSignature; +import org.apache.doris.nereids.trees.expressions.literal.StructLiteral; import org.apache.doris.nereids.trees.expressions.visitor.ExpressionVisitor; import org.apache.doris.nereids.types.ArrayType; import org.apache.doris.nereids.types.DataType; import org.apache.doris.nereids.types.IntegerType; import org.apache.doris.nereids.types.StructField; import org.apache.doris.nereids.types.StructType; +import org.apache.doris.nereids.util.ExpressionUtils; import com.google.common.base.Preconditions; import com.google.common.collect.ImmutableList; @@ -48,8 +50,8 @@ public class PosExplodeOuter extends TableGeneratingFunction implements /** * constructor with one or more arguments. */ - public PosExplodeOuter(Expression[] args) { - super("posexplode_outer", args); + public PosExplodeOuter(Expression arg, Expression... others) { + super("posexplode_outer", ExpressionUtils.mergeArguments(arg, others)); } /** constructor for withChildren and reuse signature */ @@ -62,7 +64,7 @@ private PosExplodeOuter(GeneratorFunctionParams functionParams) { */ @Override public PosExplodeOuter withChildren(List children) { - Preconditions.checkArgument(children.size() == 1); + Preconditions.checkArgument(!children.isEmpty()); return new PosExplodeOuter(getFunctionParams(children)); } @@ -85,11 +87,11 @@ public FunctionSignature computePrecision(FunctionSignature signature) { public FunctionSignature customSignature() { List arguments = new ArrayList<>(); ImmutableList.Builder structFields = ImmutableList.builder(); - structFields.add(new StructField("pos", IntegerType.INSTANCE, false, "")); + structFields.add(new StructField(PosExplode.POS_COLUMN, IntegerType.INSTANCE, false, "")); for (int i = 0; i < children.size(); i++) { if (children.get(i).getDataType().isArrayType()) { structFields.add( - new StructField("col" + (i + 1), + new StructField(StructLiteral.COL_PREFIX + (i + 1), ((ArrayType) (children.get(i)).getDataType()).getItemType(), true, "")); arguments.add(children.get(i).getDataType()); } else { diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/literal/StructLiteral.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/literal/StructLiteral.java index 0b260f4f8d0431..8844cf2923533c 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/literal/StructLiteral.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/literal/StructLiteral.java @@ -37,6 +37,7 @@ * struct literal */ public class StructLiteral extends Literal { + public static final String COL_PREFIX = "col"; private final List fields; @@ -147,7 +148,7 @@ public R accept(ExpressionVisitor visitor, C context) { public static StructType constructStructType(List fieldTypes) { ImmutableList.Builder structFields = ImmutableList.builder(); for (int i = 0; i < fieldTypes.size(); i++) { - structFields.add(new StructField("col" + (i + 1), fieldTypes.get(i), true, "")); + structFields.add(new StructField(COL_PREFIX + (i + 1), fieldTypes.get(i), true, "")); } return new StructType(structFields.build()); } diff --git a/fe/fe-core/src/test/java/org/apache/doris/nereids/rules/rewrite/PruneNestedColumnTest.java b/fe/fe-core/src/test/java/org/apache/doris/nereids/rules/rewrite/PruneNestedColumnTest.java index 6f987a6648c8ee..4ff8a82cd7cca1 100644 --- a/fe/fe-core/src/test/java/org/apache/doris/nereids/rules/rewrite/PruneNestedColumnTest.java +++ b/fe/fe-core/src/test/java/org/apache/doris/nereids/rules/rewrite/PruneNestedColumnTest.java @@ -384,6 +384,147 @@ public void testCte() throws Throwable { ); } + @Test + public void testExplode() throws Exception { + assertColumn("select 100 from tbl lateral view explode(s.data) t as item", + "struct>>>", + ImmutableList.of(path("s", "data")), + ImmutableList.of() + ); + + assertColumn("select item from tbl lateral view explode(s.data) t as item", + "struct>>>", + ImmutableList.of(path("s", "data", "*")), + ImmutableList.of() + ); + + assertColumn("select map_values(item)[1].a from tbl lateral view explode(s.data) t as item", + "struct>>>", + ImmutableList.of(path("s", "data", "*", "VALUES", "a")), + ImmutableList.of() + ); + + assertColumn("select map_values(item)[1].b from tbl lateral view explode(s.data) t as item", + "struct>>>", + ImmutableList.of(path("s", "data", "*", "VALUES", "b")), + ImmutableList.of() + ); + + assertColumn("select map_keys(item) from tbl lateral view explode(s.data) t as item", + "struct>>>", + ImmutableList.of(path("s", "data", "*", "KEYS")), + ImmutableList.of() + ); + + assertColumn("select map_keys(item), map_values(item)[1].b from tbl lateral view explode(s.data) t as item", + "struct>>>", + ImmutableList.of(path("s", "data", "*", "KEYS"), path("s", "data", "*", "VALUES", "b")), + ImmutableList.of() + ); + + assertColumn("select map_values(item1)[1].b, map_values(item2)[1].a from tbl lateral view explode(s.data, s.data) t as item1, item2", + "struct>>>", + ImmutableList.of(path("s", "data", "*", "VALUES", "a"), path("s", "data", "*", "VALUES", "b")), + ImmutableList.of() + ); + } + + @Test + public void testExplodeMap() throws Exception { + assertColumn("select 100 from tbl lateral view explode_map(s.data[1]) t as item", + "struct>>>", + ImmutableList.of(path("s", "data", "*")), + ImmutableList.of() + ); + + assertColumn("select item from tbl lateral view explode_map(s.data[1]) t as item", + "struct>>>", + ImmutableList.of(path("s", "data", "*")), + ImmutableList.of() + ); + + assertColumn("select item.col1 from tbl lateral view explode_map(s.data[1]) t as item", + "struct>>>", + ImmutableList.of(path("s", "data", "*", "KEYS")), + ImmutableList.of() + ); + + assertColumn("select item.col2.a from tbl lateral view explode_map(s.data[1]) t as item", + "struct>>>", + ImmutableList.of(path("s", "data", "*", "VALUES", "a")), + ImmutableList.of() + ); + + assertColumn("select item.col2.b from tbl lateral view explode_map(s.data[1]) t as item", + "struct>>>", + ImmutableList.of(path("s", "data", "*", "VALUES", "b")), + ImmutableList.of() + ); + + assertColumn("select item.col1, item.col2.b from tbl lateral view explode_map(s.data[1]) t as item", + "struct>>>", + ImmutableList.of(path("s", "data", "*", "KEYS"), path("s", "data", "*", "VALUES", "b")), + ImmutableList.of() + ); + + assertColumn("select k, v.b from tbl lateral view explode_map(s.data[1]) t as k, v", + "struct>>>", + ImmutableList.of(path("s", "data", "*", "KEYS"), path("s", "data", "*", "VALUES", "b")), + ImmutableList.of() + ); + } + + @Test + public void testPosExplode() throws Exception { + assertColumn("select 100 from tbl lateral view posexplode(s.data) t as item", + "struct>>>", + ImmutableList.of(path("s", "data")), + ImmutableList.of() + ); + + assertColumn("select item from tbl lateral view posexplode(s.data) t as item", + "struct>>>", + ImmutableList.of(path("s", "data")), + ImmutableList.of() + ); + + assertColumn("select item.col1[1].a from tbl lateral view posexplode(s.data) t as item", + "struct>>>", + ImmutableList.of(path("s", "data", "*", "*", "a")), + ImmutableList.of() + ); + + assertColumn("select item from tbl lateral view posexplode(s.data, s.data) t as item", + "struct>>>", + ImmutableList.of(path("s", "data")), + ImmutableList.of() + ); + + assertColumn("select item.pos from tbl lateral view posexplode(s.data, s.data) t as item", + "struct>>>", + ImmutableList.of(path("s", "data")), + ImmutableList.of() + ); + + assertColumn("select item.pos, item.col1[1].b from tbl lateral view posexplode(s.data) t as item", + "struct>>>", + ImmutableList.of(path("s", "data", "*", "*", "b")), + ImmutableList.of() + ); + + assertColumn("select item.pos, item.col1[1].b, item.col2[1].b from tbl lateral view posexplode(s.data, s.data) t as item", + "struct>>>", + ImmutableList.of(path("s", "data", "*", "*", "b")), + ImmutableList.of() + ); + + assertColumn("select item.pos, item.col1[1].b from tbl lateral view posexplode(s.data, s.data) t as item", + "struct>>>", + ImmutableList.of(path("s", "data"), path("s", "data", "*", "*", "b")), + ImmutableList.of() + ); + } + @Test public void testUnion() throws Throwable { assertColumn("select coalesce(struct_element(s, 'city'), 'abc') from (select s from tbl union all select null)a", diff --git a/fe/fe-core/src/test/java/org/apache/doris/nereids/trees/expressions/functions/generator/ExplodeOuterTest.java b/fe/fe-core/src/test/java/org/apache/doris/nereids/trees/expressions/functions/generator/ExplodeOuterTest.java index fd381a4e7d4361..a4175dd6cd3974 100644 --- a/fe/fe-core/src/test/java/org/apache/doris/nereids/trees/expressions/functions/generator/ExplodeOuterTest.java +++ b/fe/fe-core/src/test/java/org/apache/doris/nereids/trees/expressions/functions/generator/ExplodeOuterTest.java @@ -41,9 +41,10 @@ public class ExplodeOuterTest { @Test public void testGetSignatures() { // build explode_outer(array, array) expression - Expression[] args = {SlotReference.of("int", ArrayType.of(IntegerType.INSTANCE)), - SlotReference.of("str", ArrayType.of(StringType.INSTANCE))}; - ExplodeOuter explode = new ExplodeOuter(args); + Expression[] args = {SlotReference.of("str", ArrayType.of(StringType.INSTANCE))}; + ExplodeOuter explode = new ExplodeOuter( + SlotReference.of("int", ArrayType.of(IntegerType.INSTANCE)), args + ); // check signature List signatures = explode.getSignatures(); @@ -64,8 +65,8 @@ public void testGetSignatures() { @Test public void testGetSignaturesWithNull() { // build explode(null, array) expression - Expression[] args = { SlotReference.of("null", NullType.INSTANCE), SlotReference.of("int", ArrayType.of(IntegerType.INSTANCE))}; - ExplodeOuter explode = new ExplodeOuter(args); + Expression[] args = { SlotReference.of("int", ArrayType.of(IntegerType.INSTANCE))}; + ExplodeOuter explode = new ExplodeOuter(SlotReference.of("null", NullType.INSTANCE), args); // check signature List signatures = explode.getSignatures(); @@ -86,8 +87,7 @@ public void testGetSignaturesWithNull() { @Test public void testGetSignaturesWithInvalidArgument() { // build explode_outer(int) - Expression[] args = { SlotReference.of("int", IntegerType.INSTANCE) }; - ExplodeOuter explode = new ExplodeOuter(args); + ExplodeOuter explode = new ExplodeOuter(SlotReference.of("int", IntegerType.INSTANCE)); Assertions.assertThrows(AnalysisException.class, explode::getSignatures); } diff --git a/fe/fe-core/src/test/java/org/apache/doris/nereids/trees/expressions/functions/generator/ExplodeTest.java b/fe/fe-core/src/test/java/org/apache/doris/nereids/trees/expressions/functions/generator/ExplodeTest.java index 0cb61d6171a192..665ea9ad039868 100644 --- a/fe/fe-core/src/test/java/org/apache/doris/nereids/trees/expressions/functions/generator/ExplodeTest.java +++ b/fe/fe-core/src/test/java/org/apache/doris/nereids/trees/expressions/functions/generator/ExplodeTest.java @@ -41,9 +41,8 @@ public class ExplodeTest { @Test public void testGetSignatures() { // build explode(array, array) expression - Expression[] args = {SlotReference.of("int", ArrayType.of(IntegerType.INSTANCE)), - SlotReference.of("str", ArrayType.of(StringType.INSTANCE))}; - Explode explode = new Explode(args); + Expression[] args = {SlotReference.of("str", ArrayType.of(StringType.INSTANCE))}; + Explode explode = new Explode(SlotReference.of("int", ArrayType.of(IntegerType.INSTANCE)), args); // check signature List signatures = explode.getSignatures(); @@ -64,8 +63,8 @@ public void testGetSignatures() { @Test public void testGetSignaturesWithNull() { // build explode(null, array) expression - Expression[] args = { SlotReference.of("null", NullType.INSTANCE), SlotReference.of("int", ArrayType.of(IntegerType.INSTANCE))}; - Explode explode = new Explode(args); + Expression[] args = { SlotReference.of("int", ArrayType.of(IntegerType.INSTANCE))}; + Explode explode = new Explode(SlotReference.of("null", NullType.INSTANCE), args); // check signature List signatures = explode.getSignatures(); @@ -86,8 +85,7 @@ public void testGetSignaturesWithNull() { @Test public void testGetSignaturesWithInvalidArgument() { // build explode(int) - Expression[] args = { SlotReference.of("int", IntegerType.INSTANCE) }; - Explode explode = new Explode(args); + Explode explode = new Explode(SlotReference.of("int", IntegerType.INSTANCE)); Assertions.assertThrows(AnalysisException.class, explode::getSignatures); } diff --git a/fe/fe-core/src/test/java/org/apache/doris/nereids/trees/expressions/functions/generator/PosExplodeOuterTest.java b/fe/fe-core/src/test/java/org/apache/doris/nereids/trees/expressions/functions/generator/PosExplodeOuterTest.java index 36447baba6fe04..94ce3e529ab350 100644 --- a/fe/fe-core/src/test/java/org/apache/doris/nereids/trees/expressions/functions/generator/PosExplodeOuterTest.java +++ b/fe/fe-core/src/test/java/org/apache/doris/nereids/trees/expressions/functions/generator/PosExplodeOuterTest.java @@ -40,9 +40,10 @@ public class PosExplodeOuterTest { @Test public void testGetSignatures() { // build posexplode_outer(array, array) expression - Expression[] args = {SlotReference.of("int", ArrayType.of(IntegerType.INSTANCE)), - SlotReference.of("str", ArrayType.of(StringType.INSTANCE))}; - PosExplodeOuter explode = new PosExplodeOuter(args); + Expression[] args = {SlotReference.of("str", ArrayType.of(StringType.INSTANCE))}; + PosExplodeOuter explode = new PosExplodeOuter( + SlotReference.of("int", ArrayType.of(IntegerType.INSTANCE)), args + ); // check signature List signatures = explode.getSignatures(); @@ -64,8 +65,7 @@ public void testGetSignatures() { @Test public void testGetSignaturesWithInvalidArgument() { // build posexplode_outer(int) - Expression[] args = { SlotReference.of("int", IntegerType.INSTANCE) }; - PosExplodeOuter explode = new PosExplodeOuter(args); + PosExplodeOuter explode = new PosExplodeOuter(SlotReference.of("int", IntegerType.INSTANCE)); Assertions.assertThrows(AnalysisException.class, explode::getSignatures); } diff --git a/fe/fe-core/src/test/java/org/apache/doris/nereids/trees/expressions/functions/generator/PosExplodeTest.java b/fe/fe-core/src/test/java/org/apache/doris/nereids/trees/expressions/functions/generator/PosExplodeTest.java index 0009363ba71cc3..183e87e2129cf7 100644 --- a/fe/fe-core/src/test/java/org/apache/doris/nereids/trees/expressions/functions/generator/PosExplodeTest.java +++ b/fe/fe-core/src/test/java/org/apache/doris/nereids/trees/expressions/functions/generator/PosExplodeTest.java @@ -40,9 +40,8 @@ public class PosExplodeTest { @Test public void testGetSignatures() { // build posexplode(array, array) expression - Expression[] args = {SlotReference.of("int", ArrayType.of(IntegerType.INSTANCE)), - SlotReference.of("str", ArrayType.of(StringType.INSTANCE))}; - PosExplode explode = new PosExplode(args); + Expression[] args = {SlotReference.of("str", ArrayType.of(StringType.INSTANCE))}; + PosExplode explode = new PosExplode(SlotReference.of("int", ArrayType.of(IntegerType.INSTANCE)), args); // check signature List signatures = explode.getSignatures(); @@ -64,8 +63,7 @@ public void testGetSignatures() { @Test public void testGetSignaturesWithInvalidArgument() { // build posexplode(int) - Expression[] args = { SlotReference.of("int", IntegerType.INSTANCE) }; - PosExplode explode = new PosExplode(args); + PosExplode explode = new PosExplode(SlotReference.of("int", IntegerType.INSTANCE), new Expression[0]); Assertions.assertThrows(AnalysisException.class, explode::getSignatures); } From 19f685c9d0cd1d2af081f7f6bdd2ed66f7981cab Mon Sep 17 00:00:00 2001 From: 924060929 Date: Thu, 25 Dec 2025 18:00:19 +0800 Subject: [PATCH 2/2] fix --- .../rules/rewrite/AccessPathPlanCollector.java | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/rewrite/AccessPathPlanCollector.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/rewrite/AccessPathPlanCollector.java index 2625218baa64c8..e525774961a3c4 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/rewrite/AccessPathPlanCollector.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/rewrite/AccessPathPlanCollector.java @@ -45,7 +45,6 @@ import org.apache.doris.nereids.trees.plans.logical.LogicalTVFRelation; import org.apache.doris.nereids.trees.plans.logical.LogicalUnion; import org.apache.doris.nereids.trees.plans.visitor.DefaultPlanVisitor; -import org.apache.doris.nereids.types.DataType; import org.apache.doris.nereids.types.NestedColumnPrunable; import com.google.common.collect.LinkedHashMultimap; @@ -351,17 +350,4 @@ private void collectByExpressions(Plan plan, StatementContext context, boolean b exprCollector.collect(expression); } } - - private boolean argumentsHasSameType(Expression function) { - DataType firstType = null; - for (Expression argument : function.getArguments()) { - DataType argumentType = argument.getDataType(); - if (firstType == null) { - firstType = argumentType; - } else if (!firstType.equals(argumentType)) { - return false; - } - } - return true; - } }