[fix](partial update) Fix session variable enable_unique_key_partial_update will affect the behavior of insert statement when the target table is not unique table (#28321)

This commit is contained in:
bobhan1
2023-12-13 17:14:30 +08:00
committed by GitHub
parent e6e8632167
commit ac262fa176
4 changed files with 126 additions and 12 deletions

View File

@ -158,6 +158,8 @@ public class NativeInsertStmt extends InsertStmt {
private InsertType insertType = InsertType.NATIVE_INSERT;
boolean hasEmptyTargetColumns = false;
enum InsertType {
NATIVE_INSERT("insert_"),
UPDATE("update_"),
@ -545,11 +547,7 @@ public class NativeInsertStmt extends InsertStmt {
Set<String> mentionedColumns = Sets.newTreeSet(String.CASE_INSENSITIVE_ORDER);
List<String> realTargetColumnNames;
if (targetColumnNames == null) {
if (!isFromDeleteOrUpdateStmt
&& analyzer.getContext().getSessionVariable().isEnableUniqueKeyPartialUpdate()) {
throw new AnalysisException("You must explicitly specify the columns to be updated when "
+ "updating partial columns using the INSERT statement.");
}
hasEmptyTargetColumns = true;
// the mentioned columns are columns which are visible to user, so here we use
// getBaseSchema(), not getFullSchema()
for (Column col : targetTable.getBaseSchema(false)) {
@ -651,15 +649,15 @@ public class NativeInsertStmt extends InsertStmt {
}
}
if (analyzer.getContext().getSessionVariable().isEnableUniqueKeyPartialUpdate()) {
trySetPartialUpdate();
}
// check if size of select item equal with columns mentioned in statement
if (mentionedColumns.size() != queryStmt.getResultExprs().size()) {
ErrorReport.reportAnalysisException(ErrorCode.ERR_WRONG_VALUE_COUNT);
}
if (analyzer.getContext().getSessionVariable().isEnableUniqueKeyPartialUpdate()) {
trySetPartialUpdate();
}
// Check if all columns mentioned is enough
checkColumnCoverage(mentionedColumns, targetTable.getBaseSchema());
@ -1181,8 +1179,15 @@ public class NativeInsertStmt extends InsertStmt {
return;
}
OlapTable olapTable = (OlapTable) targetTable;
if (olapTable.getKeysType() != KeysType.UNIQUE_KEYS) {
return;
}
if (!olapTable.getEnableUniqueKeyMergeOnWrite()) {
throw new UserException("Partial update is only allowed in unique table with merge-on-write enabled.");
throw new UserException("Partial update is only allowed on unique table with merge-on-write enabled.");
}
if (hasEmptyTargetColumns) {
throw new AnalysisException("You must explicitly specify the columns to be updated when "
+ "updating partial columns using the INSERT statement.");
}
for (Column col : olapTable.getFullSchema()) {
boolean exists = false;

View File

@ -22,6 +22,7 @@ import org.apache.doris.analysis.SlotRef;
import org.apache.doris.catalog.Column;
import org.apache.doris.catalog.Database;
import org.apache.doris.catalog.DatabaseIf;
import org.apache.doris.catalog.KeysType;
import org.apache.doris.catalog.OlapTable;
import org.apache.doris.catalog.Partition;
import org.apache.doris.catalog.TableIf;
@ -78,7 +79,7 @@ public class BindSink implements AnalysisRuleFactory {
Pair<Database, OlapTable> pair = bind(ctx.cascadesContext, sink);
Database database = pair.first;
OlapTable table = pair.second;
boolean isPartialUpdate = sink.isPartialUpdate();
boolean isPartialUpdate = sink.isPartialUpdate() && table.getKeysType() == KeysType.UNIQUE_KEYS;
LogicalPlan child = ((LogicalPlan) sink.child());
boolean childHasSeqCol = child.getOutput().stream()
@ -106,7 +107,7 @@ public class BindSink implements AnalysisRuleFactory {
if (isPartialUpdate) {
// check the necessary conditions for partial updates
if (!table.getEnableUniqueKeyMergeOnWrite()) {
throw new AnalysisException("Partial update is only allowed in"
throw new AnalysisException("Partial update is only allowed on "
+ "unique table with merge-on-write enabled.");
}
if (sink.getColNames().isEmpty() && sink.isFromNativeInsertStmt()) {