This is an automated email from the ASF dual-hosted git repository.
yiguolei pushed a commit to branch branch-4.2
in repository https://gitbox.apache.org/repos/asf/doris.git
The following commit(s) were added to refs/heads/branch-4.2 by this push:
new 76bc755d010 branch:4.2: [fix](nullable) set SlotRef's nullable to
right value #59092 & [fix](nullable) set SlotRef's nullable to right value for
nestloop join #59310 (#68285)
76bc755d010 is described below
commit 76bc755d010c2be4436ec3431bbaac3a8b648175
Author: morrySnow <[email protected]>
AuthorDate: Mon Sep 21 18:16:16 2026 +0800
branch:4.2: [fix](nullable) set SlotRef's nullable to right value #59092 &
[fix](nullable) set SlotRef's nullable to right value for nestloop join #59310
(#68285)
picked from #59092 and #59310
---------
Co-authored-by: lichi <[email protected]>
---
.../glue/translator/PhysicalPlanTranslator.java | 208 +++++----------------
.../nereids/load/NereidsLoadPlanInfoCollector.java | 11 --
.../apache/doris/planner/AssertNumRowsNode.java | 7 +-
.../nereids_p0/test_nestloop_join_nullable.out | 191 +++++++++++++++++++
.../nereids_p0/test_nestloop_join_nullable.groovy | 114 +++++++++++
5 files changed, 355 insertions(+), 176 deletions(-)
diff --git
a/fe/fe-core/src/main/java/org/apache/doris/nereids/glue/translator/PhysicalPlanTranslator.java
b/fe/fe-core/src/main/java/org/apache/doris/nereids/glue/translator/PhysicalPlanTranslator.java
index 9c95aaa5ad0..59508d17793 100644
---
a/fe/fe-core/src/main/java/org/apache/doris/nereids/glue/translator/PhysicalPlanTranslator.java
+++
b/fe/fe-core/src/main/java/org/apache/doris/nereids/glue/translator/PhysicalPlanTranslator.java
@@ -19,6 +19,7 @@ package org.apache.doris.nereids.glue.translator;
import org.apache.doris.analysis.AggregateInfo;
import org.apache.doris.analysis.AnalyticWindow;
+import org.apache.doris.analysis.AssertNumRowsElement;
import org.apache.doris.analysis.BinaryPredicate;
import org.apache.doris.analysis.BoolLiteral;
import org.apache.doris.analysis.CompoundPredicate;
@@ -572,16 +573,6 @@ public class PhysicalPlanTranslator extends
DefaultPlanVisitor<PlanFragment, Pla
PlanTranslatorContext
context) {
PlanFragment rootFragment = hiveTableSink.child().accept(this,
context);
rootFragment.setOutputPartition(DataPartition.UNPARTITIONED);
-
- TupleDescriptor hiveTuple = context.generateTupleDesc();
- List<Column> targetTableColumns =
hiveTableSink.getTargetTable().getFullSchema();
- for (Column column : targetTableColumns) {
- SlotDescriptor slotDesc = context.addSlotDesc(hiveTuple);
- slotDesc.setType(column.getType());
- slotDesc.setColumn(column);
- slotDesc.setIsNullable(column.isAllowNull());
- slotDesc.setAutoInc(column.isAutoInc());
- }
HiveTableSink sink = new HiveTableSink((HMSExternalTable)
hiveTableSink.getTargetTable());
rootFragment.setSink(sink);
return rootFragment;
@@ -592,16 +583,6 @@ public class PhysicalPlanTranslator extends
DefaultPlanVisitor<PlanFragment, Pla
PlanTranslatorContext
context) {
PlanFragment rootFragment = icebergTableSink.child().accept(this,
context);
rootFragment.setOutputPartition(DataPartition.UNPARTITIONED);
-
- TupleDescriptor hiveTuple = context.generateTupleDesc();
- List<Column> targetTableColumns =
icebergTableSink.getTargetTable().getFullSchema();
- for (Column column : targetTableColumns) {
- SlotDescriptor slotDesc = context.addSlotDesc(hiveTuple);
- slotDesc.setType(column.getType());
- slotDesc.setColumn(column);
- slotDesc.setIsNullable(column.isAllowNull());
- slotDesc.setAutoInc(column.isAutoInc());
- }
List<Expr> outputExprs = Lists.newArrayList();
icebergTableSink.getOutput().stream().map(Slot::getExprId)
.forEach(exprId ->
outputExprs.add(context.findSlotRef(exprId)));
@@ -1135,31 +1116,21 @@ public class PhysicalPlanTranslator extends
DefaultPlanVisitor<PlanFragment, Pla
@Override
public PlanFragment visitPhysicalOneRowRelation(PhysicalOneRowRelation
oneRowRelation,
PlanTranslatorContext context) {
- List<Slot> slots = oneRowRelation.getLogicalProperties().getOutput();
+ List<Slot> slots = oneRowRelation.getOutput();
TupleDescriptor oneRowTuple = generateTupleDesc(slots, null, context);
List<Expr> legacyExprs = Lists.newArrayList();
- List<Expression> expressionList = Lists.newArrayList();
for (NamedExpression namedExpression : oneRowRelation.getProjects()) {
legacyExprs.add(ExpressionTranslator.translate(namedExpression,
context));
- expressionList.add(namedExpression);
- }
-
- for (int i = 0; i < legacyExprs.size(); i++) {
- SlotDescriptor slotDescriptor = oneRowTuple.getSlots().get(i);
- Expr expr = legacyExprs.get(i);
- slotDescriptor.setSourceExpr(expr);
- slotDescriptor.setIsNullable(slots.get(i).nullable());
}
+ List<List<Expr>> materializedConstExprLists = Lists.newArrayList();
+ materializedConstExprLists.add(legacyExprs);
UnionNode unionNode = new UnionNode(context.nextPlanNodeId(),
oneRowTuple.getId());
unionNode.setNereidsId(oneRowRelation.getId());
context.getNereidsIdToPlanNodeIdMap().put(oneRowRelation.getId(),
unionNode.getId());
unionNode.setCardinality(1L);
- List<List<Expression>> constExpressionList = Lists.newArrayList();
- constExpressionList.add(expressionList);
- finalizeForSetOperationNode(unionNode, oneRowTuple.getSlots(), new
ArrayList<>(),
- constExpressionList, new ArrayList<>(), context);
+ unionNode.setMaterializedConstExprLists(materializedConstExprLists);
PlanFragment planFragment = createPlanFragment(unionNode,
DataPartition.UNPARTITIONED, oneRowRelation);
context.addPlanFragment(planFragment);
@@ -1482,37 +1453,16 @@ public class PhysicalPlanTranslator extends
DefaultPlanVisitor<PlanFragment, Pla
// we need convert all columns to nullable in AssertNumRows node
// create a tuple for AssertNumRowsNode
- TupleDescriptor tupleDescriptor = context.generateTupleDesc();
+
// create assertNode
+ AssertNumRowsElement assertion =
ExpressionTranslator.translateAssert(assertNumRows.getAssertNumRowsElement());
+ TupleDescriptor tupleDescriptor =
generateTupleDesc(assertNumRows.getOutput(), null, context);
AssertNumRowsNode assertNumRowsNode = new
AssertNumRowsNode(context.nextPlanNodeId(),
- currentFragment.getPlanRoot(),
-
ExpressionTranslator.translateAssert(assertNumRows.getAssertNumRowsElement()),
true, tupleDescriptor);
+ currentFragment.getPlanRoot(), assertion, tupleDescriptor);
assertNumRowsNode.setChildrenDistributeExprLists(distributeExprLists);
assertNumRowsNode.setNereidsId(assertNumRows.getId());
context.getNereidsIdToPlanNodeIdMap().put(assertNumRows.getId(),
assertNumRowsNode.getId());
- // collect all child output slots
- List<TupleDescriptor> childTuples =
context.getTupleDesc(currentFragment.getPlanRoot());
- List<SlotDescriptor> childSlotDescriptors = childTuples.stream()
- .map(TupleDescriptor::getSlots)
- .flatMap(Collection::stream)
- .collect(Collectors.toList());
-
- // create output slot based on child output
- Map<ExprId, SlotReference> childOutputMap = Maps.newHashMap();
- assertNumRows.child().getOutput().stream()
- .map(SlotReference.class::cast)
- .forEach(s -> childOutputMap.put(s.getExprId(), s));
- List<SlotDescriptor> slotDescriptors = Lists.newArrayList();
- for (SlotDescriptor slot : childSlotDescriptors) {
- SlotReference sf =
childOutputMap.get(context.findExprId(slot.getId()));
- SlotDescriptor sd = context.createSlotDesc(tupleDescriptor, sf,
slot.getParent().getTable());
- slotDescriptors.add(sd);
- }
-
- // set all output slot nullable
- slotDescriptors.forEach(sd -> sd.setIsNullable(true));
-
addPlanRoot(currentFragment, assertNumRowsNode, assertNumRows);
return currentFragment;
}
@@ -1874,15 +1824,10 @@ public class PhysicalPlanTranslator extends
DefaultPlanVisitor<PlanFragment, Pla
for (SlotDescriptor leftSlotDescriptor : leftSlotDescriptors) {
SlotReference sf =
leftChildOutputMap.get(context.findExprId(leftSlotDescriptor.getId()));
SlotDescriptor sd;
- if (sf == null &&
leftSlotDescriptor.getColumn().getName().equals(Column.ROWID_COL)) {
- // TODO: temporary code for two phase read, should remove
it after refactor
- sd =
context.getDescTable().copySlotDescriptor(intermediateDescriptor,
leftSlotDescriptor);
- } else {
- sd = context.createSlotDesc(intermediateDescriptor, sf,
leftSlotDescriptor.getParent().getTable());
- if (hashOutputSlotReferenceMap.get(sf.getExprId()) !=
null) {
-
hashJoinNode.addSlotIdToHashOutputSlotIds(leftSlotDescriptor.getId());
-
hashJoinNode.getHashOutputExprSlotIdMap().put(sf.getExprId(),
leftSlotDescriptor.getId());
- }
+ sd = context.createSlotDesc(intermediateDescriptor, sf,
leftSlotDescriptor.getParent().getTable());
+ if (hashOutputSlotReferenceMap.get(sf.getExprId()) != null) {
+
hashJoinNode.addSlotIdToHashOutputSlotIds(leftSlotDescriptor.getId());
+
hashJoinNode.getHashOutputExprSlotIdMap().put(sf.getExprId(),
leftSlotDescriptor.getId());
}
leftIntermediateSlotDescriptor.add(sd);
}
@@ -1891,15 +1836,10 @@ public class PhysicalPlanTranslator extends
DefaultPlanVisitor<PlanFragment, Pla
for (SlotDescriptor rightSlotDescriptor : rightSlotDescriptors) {
SlotReference sf =
rightChildOutputMap.get(context.findExprId(rightSlotDescriptor.getId()));
SlotDescriptor sd;
- if (sf == null &&
rightSlotDescriptor.getColumn().getName().equals(Column.ROWID_COL)) {
- // TODO: temporary code for two phase read, should remove
it after refactor
- sd =
context.getDescTable().copySlotDescriptor(intermediateDescriptor,
rightSlotDescriptor);
- } else {
- sd = context.createSlotDesc(intermediateDescriptor, sf,
rightSlotDescriptor.getParent().getTable());
- if (hashOutputSlotReferenceMap.get(sf.getExprId()) !=
null) {
-
hashJoinNode.addSlotIdToHashOutputSlotIds(rightSlotDescriptor.getId());
-
hashJoinNode.getHashOutputExprSlotIdMap().put(sf.getExprId(),
rightSlotDescriptor.getId());
- }
+ sd = context.createSlotDesc(intermediateDescriptor, sf,
rightSlotDescriptor.getParent().getTable());
+ if (hashOutputSlotReferenceMap.get(sf.getExprId()) != null) {
+
hashJoinNode.addSlotIdToHashOutputSlotIds(rightSlotDescriptor.getId());
+
hashJoinNode.getHashOutputExprSlotIdMap().put(sf.getExprId(),
rightSlotDescriptor.getId());
}
rightIntermediateSlotDescriptor.add(sd);
}
@@ -1907,31 +1847,20 @@ public class PhysicalPlanTranslator extends
DefaultPlanVisitor<PlanFragment, Pla
for (SlotDescriptor leftSlotDescriptor : leftSlotDescriptors) {
SlotReference sf =
leftChildOutputMap.get(context.findExprId(leftSlotDescriptor.getId()));
SlotDescriptor sd;
- if (sf == null &&
leftSlotDescriptor.getColumn().getName().equals(Column.ROWID_COL)) {
- // TODO: temporary code for two phase read, should remove
it after refactor
- sd =
context.getDescTable().copySlotDescriptor(intermediateDescriptor,
leftSlotDescriptor);
- } else {
- sd = context.createSlotDesc(intermediateDescriptor, sf,
leftSlotDescriptor.getParent().getTable());
- // sd = context.createSlotDesc(intermediateDescriptor, sf);
- if (hashOutputSlotReferenceMap.get(sf.getExprId()) !=
null) {
-
hashJoinNode.addSlotIdToHashOutputSlotIds(leftSlotDescriptor.getId());
-
hashJoinNode.getHashOutputExprSlotIdMap().put(sf.getExprId(),
leftSlotDescriptor.getId());
- }
+ sd = context.createSlotDesc(intermediateDescriptor, sf,
leftSlotDescriptor.getParent().getTable());
+ if (hashOutputSlotReferenceMap.get(sf.getExprId()) != null) {
+
hashJoinNode.addSlotIdToHashOutputSlotIds(leftSlotDescriptor.getId());
+
hashJoinNode.getHashOutputExprSlotIdMap().put(sf.getExprId(),
leftSlotDescriptor.getId());
}
leftIntermediateSlotDescriptor.add(sd);
}
for (SlotDescriptor rightSlotDescriptor : rightSlotDescriptors) {
SlotReference sf =
rightChildOutputMap.get(context.findExprId(rightSlotDescriptor.getId()));
SlotDescriptor sd;
- if (sf == null &&
rightSlotDescriptor.getColumn().getName().equals(Column.ROWID_COL)) {
- // TODO: temporary code for two phase read, should remove
it after refactor
- sd =
context.getDescTable().copySlotDescriptor(intermediateDescriptor,
rightSlotDescriptor);
- } else {
- sd = context.createSlotDesc(intermediateDescriptor, sf,
rightSlotDescriptor.getParent().getTable());
- if (hashOutputSlotReferenceMap.get(sf.getExprId()) !=
null) {
-
hashJoinNode.addSlotIdToHashOutputSlotIds(rightSlotDescriptor.getId());
-
hashJoinNode.getHashOutputExprSlotIdMap().put(sf.getExprId(),
rightSlotDescriptor.getId());
- }
+ sd = context.createSlotDesc(intermediateDescriptor, sf,
rightSlotDescriptor.getParent().getTable());
+ if (hashOutputSlotReferenceMap.get(sf.getExprId()) != null) {
+
hashJoinNode.addSlotIdToHashOutputSlotIds(rightSlotDescriptor.getId());
+
hashJoinNode.getHashOutputExprSlotIdMap().put(sf.getExprId(),
rightSlotDescriptor.getId());
}
rightIntermediateSlotDescriptor.add(sd);
}
@@ -2109,24 +2038,14 @@ public class PhysicalPlanTranslator extends
DefaultPlanVisitor<PlanFragment, Pla
// in the intermediate tuple, so fe have to do the same, if be fix the
problem, we can change it back.
for (SlotDescriptor leftSlotDescriptor : leftSlotDescriptors) {
SlotReference sf =
leftChildOutputMap.get(context.findExprId(leftSlotDescriptor.getId()));
- SlotDescriptor sd;
- if (sf == null &&
leftSlotDescriptor.getColumn().getName().equals(Column.ROWID_COL)) {
- // TODO: temporary code for two phase read, should remove it
after refactor
- sd =
context.getDescTable().copySlotDescriptor(intermediateDescriptor,
leftSlotDescriptor);
- } else {
- sd = context.createSlotDesc(intermediateDescriptor, sf,
leftSlotDescriptor.getParent().getTable());
- }
+ SlotDescriptor sd = context.createSlotDesc(intermediateDescriptor,
sf,
+ leftSlotDescriptor.getParent().getTable());
leftIntermediateSlotDescriptor.add(sd);
}
for (SlotDescriptor rightSlotDescriptor : rightSlotDescriptors) {
SlotReference sf =
rightChildOutputMap.get(context.findExprId(rightSlotDescriptor.getId()));
- SlotDescriptor sd;
- if (sf == null &&
rightSlotDescriptor.getColumn().getName().equals(Column.ROWID_COL)) {
- // TODO: temporary code for two phase read, should remove it
after refactor
- sd =
context.getDescTable().copySlotDescriptor(intermediateDescriptor,
rightSlotDescriptor);
- } else {
- sd = context.createSlotDesc(intermediateDescriptor, sf,
rightSlotDescriptor.getParent().getTable());
- }
+ SlotDescriptor sd = context.createSlotDesc(intermediateDescriptor,
sf,
+ rightSlotDescriptor.getParent().getTable());
rightIntermediateSlotDescriptor.add(sd);
}
@@ -2508,7 +2427,6 @@ public class PhysicalPlanTranslator extends
DefaultPlanVisitor<PlanFragment, Pla
}
List<List<Expr>> distributeExprLists =
getDistributeExprs(setOperation.children().toArray(new Plan[0]));
TupleDescriptor setTuple = generateTupleDesc(setOperation.getOutput(),
null, context);
- List<SlotDescriptor> outputSlotDescs = new
ArrayList<>(setTuple.getSlots());
SetOperationNode setOperationNode;
// create setOperationNode
@@ -2523,24 +2441,33 @@ public class PhysicalPlanTranslator extends
DefaultPlanVisitor<PlanFragment, Pla
}
setOperationNode.setChildrenDistributeExprLists(distributeExprLists);
setOperationNode.setNereidsId(setOperation.getId());
- List<List<Expression>> resultExpressionLists = Lists.newArrayList();
context.getNereidsIdToPlanNodeIdMap().put(setOperation.getId(),
setOperationNode.getId());
- for (List<SlotReference> regularChildrenOutput :
setOperation.getRegularChildrenOutputs()) {
- resultExpressionLists.add(new ArrayList<>(regularChildrenOutput));
+ for (PlanFragment childFragment : childrenFragments) {
+ setOperationNode.addChild(childFragment.getPlanRoot());
}
- List<List<Expression>> constExpressionLists = Lists.newArrayList();
if (setOperation instanceof PhysicalUnion) {
- for (List<NamedExpression> unionConsts : ((PhysicalUnion)
setOperation).getConstantExprsList()) {
- constExpressionLists.add(new ArrayList<>(unionConsts));
+ List<List<Expr>> materializedConstExprLists = Lists.newArrayList();
+ for (List<NamedExpression> constExpressionList : ((PhysicalUnion)
setOperation).getConstantExprsList()) {
+ List<Expr> exprList = Lists.newArrayList();
+ for (NamedExpression expression : constExpressionList) {
+ exprList.add(ExpressionTranslator.translate(expression,
context));
+ }
+ materializedConstExprLists.add(exprList);
}
+
setOperationNode.setMaterializedConstExprLists(materializedConstExprLists);
}
- for (PlanFragment childFragment : childrenFragments) {
- setOperationNode.addChild(childFragment.getPlanRoot());
+ List<List<Expr>> materializedResultExprLists = Lists.newArrayList();
+ for (int i = 0; i < setOperation.getRegularChildrenOutputs().size();
++i) {
+ List<SlotReference> resultExpressionList =
setOperation.getRegularChildrenOutputs().get(i);
+ List<Expr> exprList = Lists.newArrayList();
+ for (int j = 0; j < resultExpressionList.size(); ++j) {
+
exprList.add(ExpressionTranslator.translate(resultExpressionList.get(j),
context));
+ }
+ materializedResultExprLists.add(exprList);
}
- finalizeForSetOperationNode(setOperationNode, outputSlotDescs,
outputSlotDescs,
- constExpressionLists, resultExpressionLists, context);
+
setOperationNode.setMaterializedResultExprLists(materializedResultExprLists);
PlanFragment setOperationFragment;
if (childrenFragments.isEmpty()) {
@@ -3529,45 +3456,6 @@ public class PhysicalPlanTranslator extends
DefaultPlanVisitor<PlanFragment, Pla
return Lists.newArrayList();
}
- private void finalizeForSetOperationNode(SetOperationNode node,
- List<SlotDescriptor>
constExprSlots,
- List<SlotDescriptor>
resultExprSlots,
- List<List<Expression>>
constExpressionLists,
- List<List<Expression>>
resultExpressionLists,
- PlanTranslatorContext context)
{
- if (node == null || constExprSlots == null || resultExprSlots == null
- || constExpressionLists == null || resultExpressionLists ==
null || context == null) {
- return;
- }
-
- List<List<Expr>> materializedConstExprLists = Lists.newArrayList();
- for (List<Expression> constExpressionList : constExpressionLists) {
- Preconditions.checkState(constExpressionList.size() ==
constExprSlots.size());
- List<Expr> exprList = Lists.newArrayList();
- for (Expression expression : constExpressionList) {
- exprList.add(ExpressionTranslator.translate(expression,
context));
- }
- materializedConstExprLists.add(exprList);
- }
- node.setMaterializedConstExprLists(materializedConstExprLists);
-
- List<List<Expr>> materializedResultExprLists = Lists.newArrayList();
- for (int i = 0; i < resultExpressionLists.size(); ++i) {
- List<Expression> resultExpressionList =
resultExpressionLists.get(i);
- List<Expr> exprList = Lists.newArrayList();
- Preconditions.checkState(resultExpressionList.size() ==
resultExprSlots.size());
- for (int j = 0; j < resultExpressionList.size(); ++j) {
-
exprList.add(ExpressionTranslator.translate(resultExpressionList.get(j),
context));
- // TODO: reconsider this, we may change nullable info in
previous nereids rules not here.
- resultExprSlots.get(j)
- .setIsNullable(resultExprSlots.get(j).getIsNullable()
|| exprList.get(j).isNullable());
- }
- materializedResultExprLists.add(exprList);
- }
- node.setMaterializedResultExprLists(materializedResultExprLists);
- Preconditions.checkState(node.getMaterializedResultExprLists().size()
== node.getChildren().size());
- }
-
// matching the simple query:
// 1. select xxx from tbl
// 2. select xxx from tbl where xxx=yyy
diff --git
a/fe/fe-core/src/main/java/org/apache/doris/nereids/load/NereidsLoadPlanInfoCollector.java
b/fe/fe-core/src/main/java/org/apache/doris/nereids/load/NereidsLoadPlanInfoCollector.java
index 6cc6ca60cf0..303ab13547d 100644
---
a/fe/fe-core/src/main/java/org/apache/doris/nereids/load/NereidsLoadPlanInfoCollector.java
+++
b/fe/fe-core/src/main/java/org/apache/doris/nereids/load/NereidsLoadPlanInfoCollector.java
@@ -423,17 +423,6 @@ public class NereidsLoadPlanInfoCollector extends
DefaultPlanVisitor<Void, PlanT
List<Slot> slots = oneRowRelation.getLogicalProperties().getOutput();
TupleDescriptor oneRowTuple = generateTupleDesc(slots, null, context);
- List<Expr> legacyExprs = oneRowRelation.getProjects()
- .stream()
- .map(expr -> ExpressionTranslator.translate(expr, context))
- .collect(Collectors.toList());
-
- for (int i = 0; i < legacyExprs.size(); i++) {
- SlotDescriptor slotDescriptor = oneRowTuple.getSlots().get(i);
- Expr expr = legacyExprs.get(i);
- slotDescriptor.setSourceExpr(expr);
- slotDescriptor.setIsNullable(slots.get(i).nullable());
- }
loadPlanInfo.srcTupleId = oneRowTuple.getId();
loadPlanInfo.srcSlotIds = new ArrayList<>(oneRowTuple.getAllSlotIds());
loadPlanInfo.srcSlotIdToDefaultValueMap = Maps.newHashMap();
diff --git
a/fe/fe-core/src/main/java/org/apache/doris/planner/AssertNumRowsNode.java
b/fe/fe-core/src/main/java/org/apache/doris/planner/AssertNumRowsNode.java
index 210743b9401..e5e8748e7f7 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/planner/AssertNumRowsNode.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/planner/AssertNumRowsNode.java
@@ -37,10 +37,8 @@ public class AssertNumRowsNode extends PlanNode {
private String subqueryString;
private AssertNumRowsElement.Assertion assertion;
- private boolean shouldConvertOutputToNullable = false;
-
public AssertNumRowsNode(PlanNodeId id, PlanNode input,
AssertNumRowsElement assertNumRowsElement,
- boolean convertToNullable, TupleDescriptor
tupleDescriptor) {
+ TupleDescriptor tupleDescriptor) {
super(id, "ASSERT NUMBER OF ROWS",
StatisticalType.ASSERT_NUM_ROWS_NODE);
this.desiredNumOfRows = assertNumRowsElement.getDesiredNumOfRows();
this.subqueryString = assertNumRowsElement.getSubqueryString();
@@ -54,7 +52,6 @@ public class AssertNumRowsNode extends PlanNode {
this.tblRefIds.addAll(input.getTblRefIds());
this.nullableTupleIds.addAll(input.getNullableTupleIds());
- this.shouldConvertOutputToNullable = convertToNullable;
}
@Override
@@ -80,7 +77,7 @@ public class AssertNumRowsNode extends PlanNode {
msg.assert_num_rows_node.setDesiredNumRows(desiredNumOfRows);
msg.assert_num_rows_node.setSubqueryString(subqueryString);
msg.assert_num_rows_node.setAssertion(assertion.toThrift());
-
msg.assert_num_rows_node.setShouldConvertOutputToNullable(shouldConvertOutputToNullable);
+ msg.assert_num_rows_node.setShouldConvertOutputToNullable(true);
}
@Override
diff --git a/regression-test/data/nereids_p0/test_nestloop_join_nullable.out
b/regression-test/data/nereids_p0/test_nestloop_join_nullable.out
new file mode 100644
index 00000000000..fe00b63ec94
--- /dev/null
+++ b/regression-test/data/nereids_p0/test_nestloop_join_nullable.out
@@ -0,0 +1,191 @@
+-- This file is automatically generated. You should know what you did if you
want to edit this
+-- !select --
+-11824.0 \N 1 \N \N
+-11824.0 \N 1 \N \N
+-11824.0 \N 1 \N \N
+-11824.0 \N 1 \N \N
+-11824.0 \N 1 \N \N
+-11824.0 \N 1 \N \N
+-11824.0 \N 1 \N \N
+-11824.0 \N 1 \N \N
+-11824.0 \N 1 \N \N
+-11824.0 \N 1 \N \N
+-11824.0 \N 1 \N \N
+-11824.0 \N 1 \N \N
+-11824.0 \N 2 \N \N
+-11824.0 \N 3 \N \N
+-11824.0 \N 4 \N \N
+-11824.0 \N 4 \N \N
+-11824.0 \N 4 \N \N
+-11824.0 \N 4 \N \N
+-11824.0 \N 4 \N \N
+-11824.0 \N 4 \N \N
+-11824.0 \N 4 \N \N
+-11824.0 \N 4 \N \N
+-11824.0 \N 4 \N \N
+-11824.0 \N 4 \N \N
+-11824.0 \N 4 \N \N
+-11824.0 \N 4 \N \N
+-11824.0 \N 6 \N \N
+-11824.0 \N 8 \N \N
+-11824.0 \N 8 \N \N
+-11824.0 \N 8 \N \N
+-11824.0 \N 8 \N \N
+-11824.0 \N 8 \N \N
+-11824.0 \N 8 \N \N
+-11824.0 \N 8 \N \N
+-11824.0 \N 8 \N \N
+-11824.0 \N 8 \N \N
+-11824.0 \N 8 \N \N
+-11824.0 \N 8 \N \N
+-11824.0 \N 8 \N \N
+-11824.0 \N 9 \N \N
+-11824.0 \N 10 \N \N
+-11824.0 \N 13 \N \N
+-11824.0 \N 13 \N \N
+-11824.0 \N 13 \N \N
+-11824.0 \N 13 \N \N
+-11824.0 \N 13 \N \N
+-11824.0 \N 13 \N \N
+-11824.0 \N 13 \N \N
+-11824.0 \N 13 \N \N
+-11824.0 \N 13 \N \N
+-11824.0 \N 13 \N \N
+-11824.0 \N 13 \N \N
+-11824.0 \N 13 \N \N
+-11824.0 \N 19 \N \N
+-11824.0 \N 20 \N \N
+-11824.0 \N 32 \N \N
+-11824.0 \N 33 \N \N
+-11824.0 -2355558 1 \N \N
+-11824.0 -1471873 3 -9832223 9832223
+-11824.0 -1471873 3 -5047939 5047939
+-11824.0 -1471873 3 -4396782 4396782
+-11824.0 -1471873 3 -1471984 1471984
+-11824.0 -1471873 3 -1471927 1471927
+-11824.0 -1471873 3 -1471885 1471885
+-11824.0 -1471873 3 -1471868 1471868
+-11824.0 -1471873 3 -1471830 1471830
+-11824.0 -1471873 3 -1456420 1456420
+-11824.0 -1471873 3 -1454151 1454151
+-11824.0 -1471873 3 -1453445 1453445
+-11824.0 -1471873 3 -1442796 1442796
+-11824.0 -1471873 7 \N \N
+-11824.0 -1471873 8 \N \N
+-11824.0 -6163 11 \N \N
+-11824.0 -126 7 -8360476 8360476
+-11824.0 -126 7 -3576192 3576192
+-11824.0 -126 7 -2925035 2925035
+-11824.0 -126 7 -237 237
+-11824.0 -126 7 -180 180
+-11824.0 -126 7 -138 138
+-11824.0 -126 7 -121 121
+-11824.0 -126 7 -83 83
+-11824.0 -126 7 15327 -15327
+-11824.0 -126 7 17596 -17596
+-11824.0 -126 7 18302 -18302
+-11824.0 -126 7 28951 -28951
+-11824.0 -126 17 \N \N
+-11824.0 -126 18 \N \N
+-11824.0 -48 11 -8360398 8360398
+-11824.0 -48 11 -3576114 3576114
+-11824.0 -48 11 -2924957 2924957
+-11824.0 -48 11 -159 159
+-11824.0 -48 11 -102 102
+-11824.0 -48 11 -60 60
+-11824.0 -48 11 -43 43
+-11824.0 -48 11 -5 5
+-11824.0 -48 11 15405 -15405
+-11824.0 -48 11 17674 -17674
+-11824.0 -48 11 18380 -18380
+-11824.0 -48 11 29029 -29029
+-11824.0 -48 26 \N \N
+-11824.0 -48 27 \N \N
+-11824.0 -39 28 \N \N
+-11824.0 43 23 \N \N
+-11824.0 44 10 -8360306 8360306
+-11824.0 44 10 -3576022 3576022
+-11824.0 44 10 -2924865 2924865
+-11824.0 44 10 -67 67
+-11824.0 44 10 -10 10
+-11824.0 44 10 32 -32
+-11824.0 44 10 49 -49
+-11824.0 44 10 87 -87
+-11824.0 44 10 15497 -15497
+-11824.0 44 10 17766 -17766
+-11824.0 44 10 18472 -18472
+-11824.0 44 10 29121 -29121
+-11824.0 44 24 \N \N
+-11824.0 44 25 \N \N
+-11824.0 79 5 -8360271 8360271
+-11824.0 79 5 -3575987 3575987
+-11824.0 79 5 -2924830 2924830
+-11824.0 79 5 -32 32
+-11824.0 79 5 25 -25
+-11824.0 79 5 67 -67
+-11824.0 79 5 84 -84
+-11824.0 79 5 122 -122
+-11824.0 79 5 15532 -15532
+-11824.0 79 5 17801 -17801
+-11824.0 79 5 18507 -18507
+-11824.0 79 5 29156 -29156
+-11824.0 79 12 \N \N
+-11824.0 79 13 \N \N
+-11824.0 92 6 -8360258 8360258
+-11824.0 92 6 -3575974 3575974
+-11824.0 92 6 -2924817 2924817
+-11824.0 92 6 -19 19
+-11824.0 92 6 38 -38
+-11824.0 92 6 80 -80
+-11824.0 92 6 97 -97
+-11824.0 92 6 135 -135
+-11824.0 92 6 15545 -15545
+-11824.0 92 6 17814 -17814
+-11824.0 92 6 18520 -18520
+-11824.0 92 6 29169 -29169
+-11824.0 92 15 \N \N
+-11824.0 92 16 \N \N
+-11824.0 121 29 \N \N
+-11824.0 7695 12 -8352655 8352655
+-11824.0 7695 12 -3568371 3568371
+-11824.0 7695 12 -2917214 2917214
+-11824.0 7695 12 7584 -7584
+-11824.0 7695 12 7641 -7641
+-11824.0 7695 12 7683 -7683
+-11824.0 7695 12 7700 -7700
+-11824.0 7695 12 7738 -7738
+-11824.0 7695 12 23148 -23148
+-11824.0 7695 12 25417 -25417
+-11824.0 7695 12 26123 -26123
+-11824.0 7695 12 36772 -36772
+-11824.0 7695 30 \N \N
+-11824.0 7695 31 \N \N
+-11824.0 9832 14 \N \N
+-11824.0 473442 2 -7886908 7886908
+-11824.0 473442 2 -3102624 3102624
+-11824.0 473442 2 -2451467 2451467
+-11824.0 473442 2 473331 -473331
+-11824.0 473442 2 473388 -473388
+-11824.0 473442 2 473430 -473430
+-11824.0 473442 2 473447 -473447
+-11824.0 473442 2 473485 -473485
+-11824.0 473442 2 488895 -488895
+-11824.0 473442 2 491164 -491164
+-11824.0 473442 2 491870 -491870
+-11824.0 473442 2 502519 -502519
+-11824.0 473442 4 \N \N
+-11824.0 473442 5 \N \N
+-11824.0 1527847 9 -6832503 6832503
+-11824.0 1527847 9 -2048219 2048219
+-11824.0 1527847 9 -1397062 1397062
+-11824.0 1527847 9 1527736 -1527736
+-11824.0 1527847 9 1527793 -1527793
+-11824.0 1527847 9 1527835 -1527835
+-11824.0 1527847 9 1527852 -1527852
+-11824.0 1527847 9 1527890 -1527890
+-11824.0 1527847 9 1543300 -1543300
+-11824.0 1527847 9 1545569 -1545569
+-11824.0 1527847 9 1546275 -1546275
+-11824.0 1527847 9 1556924 -1556924
+-11824.0 1527847 21 \N \N
+-11824.0 1527847 22 \N \N
diff --git
a/regression-test/suites/nereids_p0/test_nestloop_join_nullable.groovy
b/regression-test/suites/nereids_p0/test_nestloop_join_nullable.groovy
new file mode 100644
index 00000000000..44618ce411f
--- /dev/null
+++ b/regression-test/suites/nereids_p0/test_nestloop_join_nullable.groovy
@@ -0,0 +1,114 @@
+// 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.
+
+suite("test_nestloop_join_nullable") {
+ multi_sql '''
+ drop table if exists
table_20_undef_partitions2_keys3_properties4_distributed_by510;
+ drop table if exists
table_20_undef_partitions2_keys3_properties4_distributed_by512;
+
+ create table
table_20_undef_partitions2_keys3_properties4_distributed_by510 (
+ col_int_undef_signed int/*agg_type_placeholder*/ ,
+ col_int_undef_signed2 int/*agg_type_placeholder*/ ,
+ col_float_undef_signed float/*agg_type_placeholder*/ ,
+ col_int_undef_signed3 int/*agg_type_placeholder*/ ,
+ col_int_undef_signed4 int/*agg_type_placeholder*/ ,
+ col_int_undef_signed5 int/*agg_type_placeholder*/ ,
+ pk int/*agg_type_placeholder*/
+ ) engine=olap
+ distributed by hash(pk) buckets 10
+ properties("replication_num" = "1");
+ insert into
table_20_undef_partitions2_keys3_properties4_distributed_by510(pk,col_int_undef_signed,col_int_undef_signed2,col_float_undef_signed,col_int_undef_signed3,col_int_undef_signed4,col_int_undef_signed5)
values
(19,-538797,111,-2357243,88,null,null),(18,11035,null,-7629271,null,2400941,-12250),(17,119,8360350,null,-101,-57,-2825979),(16,93,-5,101,81,-57,null),(15,24421,3576066,null,-8351025,3094515,null),(14,-32,-53,-117,null,408662,69),(13,-28788,null,-3424,58,-16,5885342),(1
[...]
+
+ create table
table_20_undef_partitions2_keys3_properties4_distributed_by512 (
+ pk int,
+ col_int_undef_signed int ,
+ col_int_undef_signed2 int ,
+ col_float_undef_signed float ,
+ col_int_undef_signed3 int ,
+ col_int_undef_signed4 int ,
+ col_int_undef_signed5 int
+ ) engine=olap
+ DUPLICATE KEY(pk)
+ distributed by hash(pk) buckets 10
+ properties("replication_num" = "1");
+ insert into
table_20_undef_partitions2_keys3_properties4_distributed_by512(pk,col_int_undef_signed,col_int_undef_signed2,col_float_undef_signed,col_int_undef_signed3,col_int_undef_signed4,col_int_undef_signed5)
values
(19,null,-122,-4279753,-7311927,89,null),(18,-35,8334250,1537805,-112,-21552,1527847),(17,24212,null,null,62,-26157,43),(16,-3845324,null,-11824,5033341,null,121),(15,-4642469,null,-35,null,5146485,9832),(14,7780660,null,-3021705,-29468,105,-6163),(13,null,46,null,104,-
[...]
+ '''
+
+ qt_select '''
+ SELECT
+ FIRST_VALUE(t2.col_float_undef_signed) OVER (
+ ORDER BY
+ t1.col_int_undef_signed4,
+ (
+ t2.col_int_undef_signed4 + t1.col_int_undef_signed4
+ ),
+ t2.col_int_undef_signed4,
+ t1.col_int_undef_signed3,
+ t1.col_int_undef_signed5,
+ abs(t1.col_int_undef_signed),
+ t1.col_float_undef_signed,
+ t2.col_int_undef_signed
+ ),
+ LAST_VALUE(t2.col_int_undef_signed5) OVER (
+ ORDER BY
+ (
+ t2.col_float_undef_signed * t2.col_int_undef_signed
+ ),
+ t2.col_int_undef_signed5,
+ 1,
+ t2.col_float_undef_signed,
+ atan2(
+ t2.col_int_undef_signed3,
+ t1.col_int_undef_signed3
+ ),
+ t2.col_int_undef_signed,
+ t1.col_float_undef_signed,
+ t2.col_float_undef_signed
+ ),
+ RANK() OVER (
+ PARTITION BY (t1.col_int_undef_signed2 * 80954088951981892)
+ ORDER BY
+ 6,
+ ln(t2.col_int_undef_signed3),
+ t2.col_float_undef_signed,
+ t2.col_int_undef_signed,
+ (
+ t1.col_int_undef_signed4 - t2.col_int_undef_signed4
+ ),
+ t2.col_float_undef_signed,
+ t1.col_int_undef_signed5,
+ t2.col_int_undef_signed
+ ),
+ (
+ t2.col_int_undef_signed5 - t1.col_int_undef_signed2
+ ),
+ (
+ t1.col_int_undef_signed2 - t2.col_int_undef_signed5
+ )
+ from
+ table_20_undef_partitions2_keys3_properties4_distributed_by510 t1
+ RIGHT JOIN
table_20_undef_partitions2_keys3_properties4_distributed_by512 t2 ON
t1.col_int_undef_signed5 = t2.col_int_undef_signed3
+ OR t1.col_int_undef_signed3 = t1.col_int_undef_signed3
+ AND t2.col_int_undef_signed2 = t2.col_int_undef_signed2
+ order by
+ 1,
+ 2,
+ 3,
+ 4,
+ 5;
+ '''
+}
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]