[Bug](insert)fix insert wrong data on mv when stmt have multiple values (#27297)
fix insert wrong data on mv when stmt have multiple values
This commit is contained in:
@ -641,25 +641,6 @@ public class NativeInsertStmt extends InsertStmt {
|
||||
checkColumnCoverage(mentionedColumns, targetTable.getBaseSchema());
|
||||
|
||||
realTargetColumnNames = targetColumns.stream().map(Column::getName).collect(Collectors.toList());
|
||||
Map<String, Expr> slotToIndex = Maps.newTreeMap(String.CASE_INSENSITIVE_ORDER);
|
||||
for (int i = 0; i < queryStmt.getResultExprs().size(); i++) {
|
||||
Expr expr = queryStmt.getResultExprs().get(i);
|
||||
if (!(expr instanceof StringLiteral && ((StringLiteral) expr).getValue()
|
||||
.equals(SelectStmt.DEFAULT_VALUE))) {
|
||||
slotToIndex.put(realTargetColumnNames.get(i), queryStmt.getResultExprs().get(i)
|
||||
.checkTypeCompatibility(targetTable.getColumn(realTargetColumnNames.get(i)).getType()));
|
||||
}
|
||||
}
|
||||
|
||||
for (Column column : targetTable.getBaseSchema()) {
|
||||
if (!slotToIndex.containsKey(column.getName())) {
|
||||
if (column.getDefaultValue() == null) {
|
||||
slotToIndex.put(column.getName(), new NullLiteral());
|
||||
} else {
|
||||
slotToIndex.put(column.getName(), new StringLiteral(column.getDefaultValue()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// handle VALUES() or SELECT constant list
|
||||
if (isValuesOrConstantSelect) {
|
||||
@ -668,7 +649,8 @@ public class NativeInsertStmt extends InsertStmt {
|
||||
// INSERT INTO VALUES(...)
|
||||
List<ArrayList<Expr>> rows = selectStmt.getValueList().getRows();
|
||||
for (int rowIdx = 0; rowIdx < rows.size(); ++rowIdx) {
|
||||
analyzeRow(analyzer, targetColumns, rows, rowIdx, origColIdxsForExtendCols, slotToIndex, skipCheck);
|
||||
analyzeRow(analyzer, targetColumns, rows, rowIdx, origColIdxsForExtendCols, realTargetColumnNames,
|
||||
skipCheck);
|
||||
}
|
||||
|
||||
// clear these 2 structures, rebuild them using VALUES exprs
|
||||
@ -686,7 +668,8 @@ public class NativeInsertStmt extends InsertStmt {
|
||||
// `selectStmt.getResultExprs().clear();` will clear the `rows` too, causing
|
||||
// error.
|
||||
rows.add(Lists.newArrayList(selectStmt.getResultExprs()));
|
||||
analyzeRow(analyzer, targetColumns, rows, 0, origColIdxsForExtendCols, slotToIndex, skipCheck);
|
||||
analyzeRow(analyzer, targetColumns, rows, 0, origColIdxsForExtendCols, realTargetColumnNames,
|
||||
skipCheck);
|
||||
// rows may be changed in analyzeRow(), so rebuild the result exprs
|
||||
selectStmt.getResultExprs().clear();
|
||||
for (Expr expr : rows.get(0)) {
|
||||
@ -697,6 +680,8 @@ public class NativeInsertStmt extends InsertStmt {
|
||||
// INSERT INTO SELECT ... FROM tbl
|
||||
if (!origColIdxsForExtendCols.isEmpty()) {
|
||||
// extend the result expr by duplicating the related exprs
|
||||
Map<String, Expr> slotToIndex = buildSlotToIndex(queryStmt.getResultExprs(), realTargetColumnNames,
|
||||
analyzer);
|
||||
for (Pair<Integer, Column> entry : origColIdxsForExtendCols) {
|
||||
if (entry.second == null) {
|
||||
queryStmt.getResultExprs().add(queryStmt.getResultExprs().get(entry.first));
|
||||
@ -726,6 +711,8 @@ public class NativeInsertStmt extends InsertStmt {
|
||||
// expand colLabels in QueryStmt
|
||||
if (!origColIdxsForExtendCols.isEmpty()) {
|
||||
if (queryStmt.getResultExprs().size() != queryStmt.getBaseTblResultExprs().size()) {
|
||||
Map<String, Expr> slotToIndex = buildSlotToIndex(queryStmt.getBaseTblResultExprs(),
|
||||
realTargetColumnNames, analyzer);
|
||||
for (Pair<Integer, Column> entry : origColIdxsForExtendCols) {
|
||||
if (entry.second == null) {
|
||||
queryStmt.getBaseTblResultExprs().add(queryStmt.getBaseTblResultExprs().get(entry.first));
|
||||
@ -764,9 +751,35 @@ public class NativeInsertStmt extends InsertStmt {
|
||||
}
|
||||
}
|
||||
|
||||
private void analyzeRow(Analyzer analyzer, List<Column> targetColumns, List<ArrayList<Expr>> rows,
|
||||
int rowIdx, List<Pair<Integer, Column>> origColIdxsForExtendCols, Map<String, Expr> slotToIndex,
|
||||
boolean skipCheck) throws AnalysisException {
|
||||
private Map<String, Expr> buildSlotToIndex(ArrayList<Expr> row, List<String> realTargetColumnNames,
|
||||
Analyzer analyzer) throws AnalysisException {
|
||||
Map<String, Expr> slotToIndex = Maps.newTreeMap(String.CASE_INSENSITIVE_ORDER);
|
||||
for (int i = 0; i < row.size(); i++) {
|
||||
Expr expr = row.get(i);
|
||||
expr.analyze(analyzer);
|
||||
if (expr instanceof DefaultValueExpr || expr instanceof StringLiteral
|
||||
&& ((StringLiteral) expr).getValue().equals(SelectStmt.DEFAULT_VALUE)) {
|
||||
continue;
|
||||
}
|
||||
expr.analyze(analyzer);
|
||||
slotToIndex.put(realTargetColumnNames.get(i),
|
||||
expr.checkTypeCompatibility(targetTable.getColumn(realTargetColumnNames.get(i)).getType()));
|
||||
}
|
||||
for (Column column : targetTable.getBaseSchema()) {
|
||||
if (!slotToIndex.containsKey(column.getName())) {
|
||||
if (column.getDefaultValue() == null) {
|
||||
slotToIndex.put(column.getName(), new NullLiteral());
|
||||
} else {
|
||||
slotToIndex.put(column.getName(), new StringLiteral(column.getDefaultValue()));
|
||||
}
|
||||
}
|
||||
}
|
||||
return slotToIndex;
|
||||
}
|
||||
|
||||
private void analyzeRow(Analyzer analyzer, List<Column> targetColumns, List<ArrayList<Expr>> rows, int rowIdx,
|
||||
List<Pair<Integer, Column>> origColIdxsForExtendCols, List<String> realTargetColumnNames, boolean skipCheck)
|
||||
throws AnalysisException {
|
||||
// 1. check number of fields if equal with first row
|
||||
// targetColumns contains some shadow columns, which is added by system,
|
||||
// so we should minus this
|
||||
@ -778,6 +791,8 @@ public class NativeInsertStmt extends InsertStmt {
|
||||
}
|
||||
|
||||
ArrayList<Expr> row = rows.get(rowIdx);
|
||||
Map<String, Expr> slotToIndex = buildSlotToIndex(row, realTargetColumnNames, analyzer);
|
||||
|
||||
if (!origColIdxsForExtendCols.isEmpty()) {
|
||||
/**
|
||||
* we should extend the row for shadow columns.
|
||||
|
||||
Reference in New Issue
Block a user