[fix](Nereids) avoid bad cast when compute scale for round (#40776) (#40904)

pick from master #40776

for pass test case, also fix errors in computeResultInFe

computeResultInFe will generate wrong result set if output does not
match between final result and the node executing computeResultInFe
This commit is contained in:
morrySnow
2024-09-18 13:48:01 +08:00
committed by GitHub
parent 8a575d0891
commit 3336e6acbb
8 changed files with 31 additions and 22 deletions

View File

@ -579,7 +579,7 @@ public class NereidsPlanner extends Planner {
if (physicalPlan instanceof ComputeResultSet) {
Optional<SqlCacheContext> sqlCacheContext = statementContext.getSqlCacheContext();
Optional<ResultSet> resultSet = ((ComputeResultSet) physicalPlan)
.computeResultInFe(cascadesContext, sqlCacheContext);
.computeResultInFe(cascadesContext, sqlCacheContext, physicalPlan.getOutput());
if (resultSet.isPresent()) {
return resultSet;
}

View File

@ -40,8 +40,10 @@ public interface ComputePrecisionForRound extends ComputePrecision {
// If scale arg is an integer literal, or it is a cast(Integer as Integer)
// then we will try to use its value as result scale
// In any other cases, we will make sure result decimal has same scale with input.
if ((floatLength.isLiteral() && floatLength.getDataType() instanceof Int32OrLessType)
if ((floatLength.isLiteral() && !floatLength.isNullLiteral()
&& floatLength.getDataType() instanceof Int32OrLessType)
|| (floatLength instanceof Cast && floatLength.child(0).isLiteral()
&& !floatLength.child(0).isNullLiteral()
&& floatLength.child(0).getDataType() instanceof Int32OrLessType)) {
if (floatLength instanceof Cast) {
scale = ((IntegerLikeLiteral) floatLength.child(0)).getIntValue();

View File

@ -19,8 +19,10 @@ package org.apache.doris.nereids.trees.plans;
import org.apache.doris.nereids.CascadesContext;
import org.apache.doris.nereids.SqlCacheContext;
import org.apache.doris.nereids.trees.expressions.Slot;
import org.apache.doris.qe.ResultSet;
import java.util.List;
import java.util.Optional;
/**
@ -51,5 +53,6 @@ import java.util.Optional;
* </pre>
*/
public interface ComputeResultSet {
Optional<ResultSet> computeResultInFe(CascadesContext cascadesContext, Optional<SqlCacheContext> sqlCacheContext);
Optional<ResultSet> computeResultInFe(CascadesContext cascadesContext, Optional<SqlCacheContext> sqlCacheContext,
List<Slot> outputSlots);
}

View File

@ -116,11 +116,9 @@ public class PhysicalEmptyRelation extends PhysicalRelation implements EmptyRela
@Override
public Optional<ResultSet> computeResultInFe(CascadesContext cascadesContext,
Optional<SqlCacheContext> sqlCacheContext) {
Optional<SqlCacheContext> sqlCacheContext, List<Slot> outputSlots) {
List<Column> columns = Lists.newArrayList();
List<Slot> outputSlots = getOutput();
for (int i = 0; i < outputSlots.size(); i++) {
NamedExpression output = outputSlots.get(i);
for (NamedExpression output : outputSlots) {
columns.add(new Column(output.getName(), output.getDataType().toCatalogDataType()));
}

View File

@ -28,6 +28,7 @@ import org.apache.doris.nereids.properties.LogicalProperties;
import org.apache.doris.nereids.properties.PhysicalProperties;
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.literal.Literal;
import org.apache.doris.nereids.trees.plans.ComputeResultSet;
import org.apache.doris.nereids.trees.plans.Plan;
@ -136,19 +137,24 @@ public class PhysicalOneRowRelation extends PhysicalRelation implements OneRowRe
@Override
public Optional<ResultSet> computeResultInFe(
CascadesContext cascadesContext, Optional<SqlCacheContext> sqlCacheContext) {
CascadesContext cascadesContext, Optional<SqlCacheContext> sqlCacheContext, List<Slot> outputSlots) {
List<Column> columns = Lists.newArrayList();
List<String> data = Lists.newArrayList();
for (int i = 0; i < projects.size(); i++) {
NamedExpression item = projects.get(i);
NamedExpression output = getOutput().get(i);
Expression expr = item.child(0);
if (expr instanceof Literal) {
LiteralExpr legacyExpr = ((Literal) expr).toLegacyLiteral();
columns.add(new Column(output.getName(), output.getDataType().toCatalogDataType()));
data.add(legacyExpr.getStringValueInFe(cascadesContext.getStatementContext().getFormatOptions()));
} else {
return Optional.empty();
for (Slot outputSlot : outputSlots) {
for (int i = 0; i < projects.size(); i++) {
NamedExpression item = projects.get(i);
NamedExpression output = getOutput().get(i);
if (!outputSlot.getExprId().equals(output.getExprId())) {
continue;
}
Expression expr = item.child(0);
if (expr instanceof Literal) {
LiteralExpr legacyExpr = ((Literal) expr).toLegacyLiteral();
columns.add(new Column(output.getName(), output.getDataType().toCatalogDataType()));
data.add(legacyExpr.getStringValueInFe(cascadesContext.getStatementContext().getFormatOptions()));
} else {
return Optional.empty();
}
}
}

View File

@ -24,6 +24,7 @@ import org.apache.doris.nereids.properties.LogicalProperties;
import org.apache.doris.nereids.properties.PhysicalProperties;
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.plans.ComputeResultSet;
import org.apache.doris.nereids.trees.plans.Plan;
import org.apache.doris.nereids.trees.plans.PlanType;
@ -129,10 +130,10 @@ public class PhysicalResultSink<CHILD_TYPE extends Plan> extends PhysicalSink<CH
@Override
public Optional<ResultSet> computeResultInFe(
CascadesContext cascadesContext, Optional<SqlCacheContext> sqlCacheContext) {
CascadesContext cascadesContext, Optional<SqlCacheContext> sqlCacheContext, List<Slot> outputSlots) {
CHILD_TYPE child = child();
if (child instanceof ComputeResultSet) {
return ((ComputeResultSet) child).computeResultInFe(cascadesContext, sqlCacheContext);
return ((ComputeResultSet) child).computeResultInFe(cascadesContext, sqlCacheContext, outputSlots);
} else {
return Optional.empty();
}

View File

@ -167,7 +167,7 @@ public class PhysicalSqlCache extends PhysicalLeaf implements SqlCache, TreeStri
@Override
public Optional<ResultSet> computeResultInFe(
CascadesContext cascadesContext, Optional<SqlCacheContext> sqlCacheContext) {
CascadesContext cascadesContext, Optional<SqlCacheContext> sqlCacheContext, List<Slot> outputSlots) {
return resultSet;
}
}