[fix](update) Update set value should consider sequence column (#31626)

When using update command to set column value, if the column is sequence column, the column 'DORIS_SEQUENCE_COL' should also be set to the same value.
This commit is contained in:
huanghaibin
2024-03-05 20:45:28 +08:00
committed by yiguolei
parent 679c7657f6
commit 1d2d0bd411
5 changed files with 122 additions and 15 deletions

View File

@ -35,6 +35,7 @@ import org.apache.doris.qe.SessionVariable;
import com.google.common.collect.Lists;
import java.util.List;
import java.util.Optional;
import java.util.Set;
import java.util.TreeSet;
@ -211,12 +212,23 @@ public class UpdateStmt extends DdlStmt {
&& !hasVariant) {
isPartialUpdate = true;
}
Optional<Column> sequenceMapCol = Optional.empty();
OlapTable olapTable = (OlapTable) targetTable;
if (olapTable.hasSequenceCol() && olapTable.getSequenceMapCol() != null) {
sequenceMapCol = olapTable.getFullSchema().stream()
.filter(col -> col.getName().equalsIgnoreCase(olapTable.getSequenceMapCol())).findFirst();
}
for (Column column : targetTable.getColumns()) {
Expr expr = new SlotRef(targetTableRef.getAliasAsName(), column.getName());
boolean existInExpr = false;
for (BinaryPredicate setExpr : setExprs) {
Expr lhs = setExpr.getChild(0);
if (((SlotRef) lhs).getColumn().equals(column)) {
Column exprColumn = ((SlotRef) lhs).getColumn();
// when updating the sequence map column, the real sequence column need to set with the same value.
boolean isSequenceMapColumn = sequenceMapCol.isPresent()
&& exprColumn.equals(sequenceMapCol.get());
if (exprColumn.equals(column) || (olapTable.hasSequenceCol()
&& column.equals(olapTable.getSequenceCol()) && isSequenceMapColumn)) {
expr = setExpr.getChild(1);
existInExpr = true;
}

View File

@ -110,6 +110,7 @@ public class UpdateCommand extends Command implements ForwardWithSync, Explainab
}
List<NamedExpression> selectItems = Lists.newArrayList();
String tableName = tableAlias != null ? tableAlias : targetTable.getName();
Expression setExpr = null;
for (Column column : targetTable.getFullSchema()) {
// if it sets sequence column in stream load phase, the sequence map column is null, we query it.
if (!column.isVisible() && !column.isSequenceColumn()) {
@ -117,12 +118,21 @@ public class UpdateCommand extends Command implements ForwardWithSync, Explainab
}
if (colNameToExpression.containsKey(column.getName())) {
Expression expr = colNameToExpression.get(column.getName());
// when updating the sequence map column, the real sequence column need to set with the same value.
boolean isSequenceMapColumn = targetTable.hasSequenceCol()
&& targetTable.getSequenceMapCol() != null
&& column.getName().equalsIgnoreCase(targetTable.getSequenceMapCol());
if (setExpr == null && isSequenceMapColumn) {
setExpr = expr;
}
selectItems.add(expr instanceof UnboundSlot
? ((NamedExpression) expr)
: new UnboundAlias(expr));
colNameToExpression.remove(column.getName());
} else {
if (column.hasOnUpdateDefaultValue()) {
if (column.isSequenceColumn() && setExpr != null) {
selectItems.add(new UnboundAlias(setExpr, column.getName()));
} else if (column.hasOnUpdateDefaultValue()) {
Expression defualtValueExpression =
new NereidsParser().parseExpression(column.getOnUpdateDefaultValueExpr()
.toSqlWithoutTbl());
@ -141,7 +151,6 @@ public class UpdateCommand extends Command implements ForwardWithSync, Explainab
if (cte.isPresent()) {
logicalQuery = ((LogicalPlan) cte.get().withChildren(logicalQuery));
}
boolean isPartialUpdate = targetTable.getEnableUniqueKeyMergeOnWrite()
&& selectItems.size() < targetTable.getColumns().size()
&& !targetTable.hasVariantColumns();