This is an automated email from the ASF dual-hosted git repository. gavinchou pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/doris.git
The following commit(s) were added to refs/heads/master by this push: new 2f3a9c43ad8 [Fix](paritial update) Fix the case of partial update failing in cloud mode (#37151) 2f3a9c43ad8 is described below commit 2f3a9c43ad8de966b55199984c086be504b7327c Author: abmdocrt <yukang.lian2...@gmail.com> AuthorDate: Fri Jul 5 23:55:48 2024 +0800 [Fix](paritial update) Fix the case of partial update failing in cloud mode (#37151) Problem: The `test_new_partial_update` case fails to run in cloud mode, but it passes in local mode. Reason: In PR #35917, we introduced a new table attribute `enable_light_delete`. When executing schema changes with `alter table set xxx` statements, the local and cloud modes process the logic differently. The cloud mode has its unique processing logic, which was not addressed in the mentioned PR, leading to failures in the cloud environment. Solution: To resolve the issue, we need to complete the missing schema change logic for the cloud mode. Once this is implemented, the problem should be resolved. --- .../main/java/org/apache/doris/common/Config.java | 2 +- .../org/apache/doris/alter/CloudRollupJobV2.java | 29 ++++----- .../apache/doris/alter/CloudSchemaChangeJobV2.java | 33 +++++----- .../apache/doris/alter/SchemaChangeHandler.java | 12 ++-- .../java/org/apache/doris/analysis/DeleteStmt.java | 2 +- .../analysis/ModifyTablePropertiesClause.java | 17 +++--- .../main/java/org/apache/doris/catalog/Env.java | 4 +- .../java/org/apache/doris/catalog/OlapTable.java | 8 +-- .../org/apache/doris/catalog/TableProperty.java | 10 +-- .../cloud/alter/CloudSchemaChangeHandler.java | 33 +++++++++- .../cloud/datasource/CloudInternalCatalog.java | 8 ++- .../apache/doris/common/util/PropertyAnalyzer.java | 14 ++--- .../apache/doris/datasource/InternalCatalog.java | 20 +++--- .../trees/plans/commands/DeleteFromCommand.java | 2 +- .../analysis/CreateTableAsSelectStmtTest.java | 2 +- gensrc/proto/cloud.proto | 1 + gensrc/proto/olap_file.proto | 1 + .../data/query_p0/system/test_table_options.out | 12 ++-- .../test_new_partial_update_delete.groovy | 71 +++++++++++++++++----- 19 files changed, 179 insertions(+), 102 deletions(-) diff --git a/fe/fe-common/src/main/java/org/apache/doris/common/Config.java b/fe/fe-common/src/main/java/org/apache/doris/common/Config.java index 6c3b19b37fa..1716760ff61 100644 --- a/fe/fe-common/src/main/java/org/apache/doris/common/Config.java +++ b/fe/fe-common/src/main/java/org/apache/doris/common/Config.java @@ -2635,7 +2635,7 @@ public class Config extends ConfigBase { + "DELETE statements, but partial column updates after a DELETE may result in erroneous data. " + "If disabled, it will reduce the performance of DELETE statements to ensure accuracy." }) - public static boolean enable_mow_delete_on_predicate = false; + public static boolean enable_mow_light_delete = false; @ConfField(description = { "是否开启 Proxy Protocol 支持", diff --git a/fe/fe-core/src/main/java/org/apache/doris/alter/CloudRollupJobV2.java b/fe/fe-core/src/main/java/org/apache/doris/alter/CloudRollupJobV2.java index 688c2cd17cd..4f2a241e089 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/alter/CloudRollupJobV2.java +++ b/fe/fe-core/src/main/java/org/apache/doris/alter/CloudRollupJobV2.java @@ -196,20 +196,21 @@ public class CloudRollupJobV2 extends RollupJobV2 { ((CloudInternalCatalog) Env.getCurrentInternalCatalog()) .createTabletMetaBuilder(tableId, rollupIndexId, partitionId, rollupTablet, tabletType, rollupSchemaHash, - rollupKeysType, rollupShortKeyColumnCount, tbl.getCopiedBfColumns(), - tbl.getBfFpp(), null, rollupSchema, - tbl.getDataSortInfo(), tbl.getCompressionType(), tbl.getStoragePolicy(), - tbl.isInMemory(), true, - tbl.getName(), tbl.getTTLSeconds(), - tbl.getEnableUniqueKeyMergeOnWrite(), tbl.storeRowColumn(), - tbl.getBaseSchemaVersion(), tbl.getCompactionPolicy(), - tbl.getTimeSeriesCompactionGoalSizeMbytes(), - tbl.getTimeSeriesCompactionFileCountThreshold(), - tbl.getTimeSeriesCompactionTimeThresholdSeconds(), - tbl.getTimeSeriesCompactionEmptyRowsetsThreshold(), - tbl.getTimeSeriesCompactionLevelThreshold(), - tbl.disableAutoCompaction(), - tbl.getRowStoreColumnsUniqueIds(rowStoreColumns)); + rollupKeysType, rollupShortKeyColumnCount, tbl.getCopiedBfColumns(), + tbl.getBfFpp(), null, rollupSchema, + tbl.getDataSortInfo(), tbl.getCompressionType(), tbl.getStoragePolicy(), + tbl.isInMemory(), true, + tbl.getName(), tbl.getTTLSeconds(), + tbl.getEnableUniqueKeyMergeOnWrite(), tbl.storeRowColumn(), + tbl.getBaseSchemaVersion(), tbl.getCompactionPolicy(), + tbl.getTimeSeriesCompactionGoalSizeMbytes(), + tbl.getTimeSeriesCompactionFileCountThreshold(), + tbl.getTimeSeriesCompactionTimeThresholdSeconds(), + tbl.getTimeSeriesCompactionEmptyRowsetsThreshold(), + tbl.getTimeSeriesCompactionLevelThreshold(), + tbl.disableAutoCompaction(), + tbl.getRowStoreColumnsUniqueIds(rowStoreColumns), + tbl.getEnableMowLightDelete()); requestBuilder.addTabletMetas(builder); } // end for rollupTablets ((CloudInternalCatalog) Env.getCurrentInternalCatalog()) diff --git a/fe/fe-core/src/main/java/org/apache/doris/alter/CloudSchemaChangeJobV2.java b/fe/fe-core/src/main/java/org/apache/doris/alter/CloudSchemaChangeJobV2.java index 3968f2d274f..6a4584c733b 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/alter/CloudSchemaChangeJobV2.java +++ b/fe/fe-core/src/main/java/org/apache/doris/alter/CloudSchemaChangeJobV2.java @@ -213,21 +213,24 @@ public class CloudSchemaChangeJobV2 extends SchemaChangeJobV2 { for (Tablet shadowTablet : shadowIdx.getTablets()) { OlapFile.TabletMetaCloudPB.Builder builder = ((CloudInternalCatalog) Env.getCurrentInternalCatalog()) - .createTabletMetaBuilder(tableId, shadowIdxId, - partitionId, shadowTablet, tbl.getPartitionInfo().getTabletType(partitionId), - shadowSchemaHash, originKeysType, shadowShortKeyColumnCount, bfColumns, - bfFpp, tabletIndexes, shadowSchema, tbl.getDataSortInfo(), tbl.getCompressionType(), - tbl.getStoragePolicy(), tbl.isInMemory(), true, - tbl.getName(), tbl.getTTLSeconds(), - tbl.getEnableUniqueKeyMergeOnWrite(), tbl.storeRowColumn(), - shadowSchemaVersion, tbl.getCompactionPolicy(), - tbl.getTimeSeriesCompactionGoalSizeMbytes(), - tbl.getTimeSeriesCompactionFileCountThreshold(), - tbl.getTimeSeriesCompactionTimeThresholdSeconds(), - tbl.getTimeSeriesCompactionEmptyRowsetsThreshold(), - tbl.getTimeSeriesCompactionLevelThreshold(), - tbl.disableAutoCompaction(), - tbl.getRowStoreColumnsUniqueIds(rowStoreColumns)); + .createTabletMetaBuilder(tableId, shadowIdxId, + partitionId, shadowTablet, + tbl.getPartitionInfo().getTabletType(partitionId), + shadowSchemaHash, originKeysType, shadowShortKeyColumnCount, bfColumns, + bfFpp, tabletIndexes, shadowSchema, tbl.getDataSortInfo(), + tbl.getCompressionType(), + tbl.getStoragePolicy(), tbl.isInMemory(), true, + tbl.getName(), tbl.getTTLSeconds(), + tbl.getEnableUniqueKeyMergeOnWrite(), tbl.storeRowColumn(), + shadowSchemaVersion, tbl.getCompactionPolicy(), + tbl.getTimeSeriesCompactionGoalSizeMbytes(), + tbl.getTimeSeriesCompactionFileCountThreshold(), + tbl.getTimeSeriesCompactionTimeThresholdSeconds(), + tbl.getTimeSeriesCompactionEmptyRowsetsThreshold(), + tbl.getTimeSeriesCompactionLevelThreshold(), + tbl.disableAutoCompaction(), + tbl.getRowStoreColumnsUniqueIds(rowStoreColumns), + tbl.getEnableMowLightDelete()); requestBuilder.addTabletMetas(builder); } // end for rollupTablets ((CloudInternalCatalog) Env.getCurrentInternalCatalog()) diff --git a/fe/fe-core/src/main/java/org/apache/doris/alter/SchemaChangeHandler.java b/fe/fe-core/src/main/java/org/apache/doris/alter/SchemaChangeHandler.java index 8da664321b5..7d581272648 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/alter/SchemaChangeHandler.java +++ b/fe/fe-core/src/main/java/org/apache/doris/alter/SchemaChangeHandler.java @@ -2285,7 +2285,7 @@ public class SchemaChangeHandler extends AlterHandler { || properties.containsKey(PropertyAnalyzer.PROPERTIES_TIME_SERIES_COMPACTION_TIME_THRESHOLD_SECONDS) || properties.containsKey(PropertyAnalyzer.PROPERTIES_GROUP_COMMIT_INTERVAL_MS) || properties.containsKey(PropertyAnalyzer.PROPERTIES_GROUP_COMMIT_DATA_BYTES) - || properties.containsKey(PropertyAnalyzer.PROPERTIES_ENABLE_MOW_DELETE_ON_DELETE_PREDICATE) + || properties.containsKey(PropertyAnalyzer.PROPERTIES_ENABLE_MOW_LIGHT_DELETE) || properties.containsKey(PropertyAnalyzer.PROPERTIES_ENABLE_SINGLE_REPLICA_COMPACTION) || properties.containsKey(PropertyAnalyzer.PROPERTIES_DISABLE_AUTO_COMPACTION) || properties.containsKey(PropertyAnalyzer.PROPERTIES_SKIP_WRITE_INDEX_ON_LOAD) @@ -2366,7 +2366,7 @@ public class SchemaChangeHandler extends AlterHandler { if (isInMemory < 0 && storagePolicyId < 0 && compactionPolicy == null && timeSeriesCompactionConfig.isEmpty() && !properties.containsKey(PropertyAnalyzer.PROPERTIES_IS_BEING_SYNCED) - && !properties.containsKey(PropertyAnalyzer.PROPERTIES_ENABLE_MOW_DELETE_ON_DELETE_PREDICATE) + && !properties.containsKey(PropertyAnalyzer.PROPERTIES_ENABLE_MOW_LIGHT_DELETE) && !properties.containsKey(PropertyAnalyzer.PROPERTIES_ENABLE_SINGLE_REPLICA_COMPACTION) && !properties.containsKey(PropertyAnalyzer.PROPERTIES_DISABLE_AUTO_COMPACTION) && !properties.containsKey(PropertyAnalyzer.PROPERTIES_GROUP_COMMIT_INTERVAL_MS) @@ -2387,11 +2387,11 @@ public class SchemaChangeHandler extends AlterHandler { "enable_single_replica_compaction property is not supported for merge-on-write table"); } - String enableMowDeleteOnDeletePredicate = properties.get( - PropertyAnalyzer.PROPERTIES_ENABLE_MOW_DELETE_ON_DELETE_PREDICATE); - if (!enableUniqueKeyMergeOnWrite && Boolean.getBoolean(enableMowDeleteOnDeletePredicate)) { + String enableMowLightDelete = properties.get( + PropertyAnalyzer.PROPERTIES_ENABLE_MOW_LIGHT_DELETE); + if (enableMowLightDelete != null && !enableUniqueKeyMergeOnWrite) { throw new UserException( - "enable_mow_delete_on_delete_predicate property is not supported for unique merge-on-read table"); + "enable_mow_light_delete property is only supported for unique merge-on-write table"); } String disableAutoCompactionBoolean = properties.get(PropertyAnalyzer.PROPERTIES_DISABLE_AUTO_COMPACTION); diff --git a/fe/fe-core/src/main/java/org/apache/doris/analysis/DeleteStmt.java b/fe/fe-core/src/main/java/org/apache/doris/analysis/DeleteStmt.java index 9de51aebd40..369eb126597 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/analysis/DeleteStmt.java +++ b/fe/fe-core/src/main/java/org/apache/doris/analysis/DeleteStmt.java @@ -124,7 +124,7 @@ public class DeleteStmt extends DdlStmt implements NotFallbackInParser { // analyze predicate if ((fromClause == null && !((OlapTable) targetTable).getEnableUniqueKeyMergeOnWrite()) - || (fromClause == null && ((OlapTable) targetTable).getEnableDeleteOnDeletePredicate())) { + || (fromClause == null && ((OlapTable) targetTable).getEnableMowLightDelete())) { if (wherePredicate == null) { throw new AnalysisException("Where clause is not set"); } diff --git a/fe/fe-core/src/main/java/org/apache/doris/analysis/ModifyTablePropertiesClause.java b/fe/fe-core/src/main/java/org/apache/doris/analysis/ModifyTablePropertiesClause.java index 0c56c2f00cc..85b00394326 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/analysis/ModifyTablePropertiesClause.java +++ b/fe/fe-core/src/main/java/org/apache/doris/analysis/ModifyTablePropertiesClause.java @@ -270,14 +270,14 @@ public class ModifyTablePropertiesClause extends AlterTableClause { } this.needTableStable = false; this.opType = AlterOpType.MODIFY_TABLE_PROPERTY_SYNC; - } else if (properties.containsKey(PropertyAnalyzer.PROPERTIES_ENABLE_MOW_DELETE_ON_DELETE_PREDICATE)) { - if (!properties.get(PropertyAnalyzer.PROPERTIES_ENABLE_MOW_DELETE_ON_DELETE_PREDICATE) + } else if (properties.containsKey(PropertyAnalyzer.PROPERTIES_ENABLE_MOW_LIGHT_DELETE)) { + if (!properties.get(PropertyAnalyzer.PROPERTIES_ENABLE_MOW_LIGHT_DELETE) .equalsIgnoreCase("true") && !properties.get(PropertyAnalyzer - .PROPERTIES_ENABLE_MOW_DELETE_ON_DELETE_PREDICATE).equalsIgnoreCase("false")) { + .PROPERTIES_ENABLE_MOW_LIGHT_DELETE).equalsIgnoreCase("false")) { throw new AnalysisException( "Property " - + PropertyAnalyzer.PROPERTIES_ENABLE_SINGLE_REPLICA_COMPACTION + + PropertyAnalyzer.PROPERTIES_ENABLE_MOW_LIGHT_DELETE + " should be set to true or false"); } OlapTable table = null; @@ -285,13 +285,10 @@ public class ModifyTablePropertiesClause extends AlterTableClause { table = (OlapTable) (Env.getCurrentInternalCatalog().getDbOrAnalysisException(tableName.getDb()) .getTableOrAnalysisException(tableName.getTbl())); } - String enableMowDeleteOnDeletePredicate = properties.get( - PropertyAnalyzer.PROPERTIES_ENABLE_MOW_DELETE_ON_DELETE_PREDICATE); - if (!(table == null) && !table.getEnableUniqueKeyMergeOnWrite() && Boolean.getBoolean( - enableMowDeleteOnDeletePredicate)) { + if (table == null || !table.getEnableUniqueKeyMergeOnWrite()) { throw new AnalysisException( - "enable_mow_delete_on_delete_predicate property is " - + "not supported for unique merge-on-read table"); + "enable_mow_light_delete property is " + + "only supported for unique merge-on-write table"); } this.needTableStable = false; this.opType = AlterOpType.MODIFY_TABLE_PROPERTY_SYNC; diff --git a/fe/fe-core/src/main/java/org/apache/doris/catalog/Env.java b/fe/fe-core/src/main/java/org/apache/doris/catalog/Env.java index 22e7c7218d9..6f03e141036 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/catalog/Env.java +++ b/fe/fe-core/src/main/java/org/apache/doris/catalog/Env.java @@ -3596,9 +3596,9 @@ public class Env { // enable delete on delete predicate if (olapTable.getKeysType() == KeysType.UNIQUE_KEYS && olapTable.getEnableUniqueKeyMergeOnWrite()) { - sb.append(",\n\"").append(PropertyAnalyzer.PROPERTIES_ENABLE_MOW_DELETE_ON_DELETE_PREDICATE) + sb.append(",\n\"").append(PropertyAnalyzer.PROPERTIES_ENABLE_MOW_LIGHT_DELETE) .append("\" = \""); - sb.append(olapTable.getEnableDeleteOnDeletePredicate()).append("\""); + sb.append(olapTable.getEnableMowLightDelete()).append("\""); } // enable duplicate without keys by default diff --git a/fe/fe-core/src/main/java/org/apache/doris/catalog/OlapTable.java b/fe/fe-core/src/main/java/org/apache/doris/catalog/OlapTable.java index 471cbdf0ec6..005bd1acaa6 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/catalog/OlapTable.java +++ b/fe/fe-core/src/main/java/org/apache/doris/catalog/OlapTable.java @@ -1324,12 +1324,12 @@ public class OlapTable extends Table implements MTMVRelatedTableIf, GsonPostProc return null; } - public void setEnableDeleteOnDeletePredicate(boolean enable) { - getOrCreatTableProperty().setEnableDeleteOnDeletePredicate(enable); + public void setEnableMowLightDelete(boolean enable) { + getOrCreatTableProperty().setEnableMowLightDelete(enable); } - public boolean getEnableDeleteOnDeletePredicate() { - return getOrCreatTableProperty().getEnableDelteOnDeletePredicate(); + public boolean getEnableMowLightDelete() { + return getOrCreatTableProperty().getEnableMowLightDelete(); } public void setGroupCommitIntervalMs(int groupCommitInterValMs) { diff --git a/fe/fe-core/src/main/java/org/apache/doris/catalog/TableProperty.java b/fe/fe-core/src/main/java/org/apache/doris/catalog/TableProperty.java index 59c483020fe..f453dd28e8c 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/catalog/TableProperty.java +++ b/fe/fe-core/src/main/java/org/apache/doris/catalog/TableProperty.java @@ -568,14 +568,14 @@ public class TableProperty implements Writable, GsonPostProcessable { PropertyAnalyzer.ENABLE_UNIQUE_KEY_MERGE_ON_WRITE, "false")); } - public void setEnableDeleteOnDeletePredicate(boolean enable) { - properties.put(PropertyAnalyzer.PROPERTIES_ENABLE_MOW_DELETE_ON_DELETE_PREDICATE, Boolean.toString(enable)); + public void setEnableMowLightDelete(boolean enable) { + properties.put(PropertyAnalyzer.PROPERTIES_ENABLE_MOW_LIGHT_DELETE, Boolean.toString(enable)); } - public boolean getEnableDelteOnDeletePredicate() { + public boolean getEnableMowLightDelete() { return Boolean.parseBoolean(properties.getOrDefault( - PropertyAnalyzer.PROPERTIES_ENABLE_MOW_DELETE_ON_DELETE_PREDICATE, - Boolean.toString(PropertyAnalyzer.PROPERTIES_ENABLE_MOW_DELETE_ON_DELETE_PREDICATE_DEFAULT_VALUE))); + PropertyAnalyzer.PROPERTIES_ENABLE_MOW_LIGHT_DELETE, + Boolean.toString(PropertyAnalyzer.PROPERTIES_ENABLE_MOW_LIGHT_DELETE_DEFAULT_VALUE))); } public void setSequenceMapCol(String colName) { diff --git a/fe/fe-core/src/main/java/org/apache/doris/cloud/alter/CloudSchemaChangeHandler.java b/fe/fe-core/src/main/java/org/apache/doris/cloud/alter/CloudSchemaChangeHandler.java index ba92857b38d..e48b8a745a3 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/cloud/alter/CloudSchemaChangeHandler.java +++ b/fe/fe-core/src/main/java/org/apache/doris/cloud/alter/CloudSchemaChangeHandler.java @@ -99,7 +99,8 @@ public class CloudSchemaChangeHandler extends SchemaChangeHandler { || properties.containsKey(PropertyAnalyzer.PROPERTIES_TIME_SERIES_COMPACTION_TIME_THRESHOLD_SECONDS) || properties.containsKey(PropertyAnalyzer.PROPERTIES_TIME_SERIES_COMPACTION_EMPTY_ROWSETS_THRESHOLD) || properties.containsKey(PropertyAnalyzer.PROPERTIES_TIME_SERIES_COMPACTION_LEVEL_THRESHOLD) - || properties.containsKey(PropertyAnalyzer.PROPERTIES_DISABLE_AUTO_COMPACTION)); + || properties.containsKey(PropertyAnalyzer.PROPERTIES_DISABLE_AUTO_COMPACTION) + || properties.containsKey(PropertyAnalyzer.PROPERTIES_ENABLE_MOW_LIGHT_DELETE)); if (properties.size() != 1) { throw new UserException("Can only set one table property at a time"); @@ -292,6 +293,29 @@ public class CloudSchemaChangeHandler extends SchemaChangeHandler { } param.disableAutoCompaction = disableAutoCompaction; param.type = UpdatePartitionMetaParam.TabletMetaType.DISABLE_AUTO_COMPACTION; + } else if (properties.containsKey(PropertyAnalyzer.PROPERTIES_ENABLE_MOW_LIGHT_DELETE)) { + boolean enableMowLightDelete = Boolean.parseBoolean(properties.get(PropertyAnalyzer + .PROPERTIES_ENABLE_MOW_LIGHT_DELETE)); + olapTable.readLock(); + try { + if (enableMowLightDelete + == olapTable.getEnableMowLightDelete()) { + LOG.info("enableMowLightDelete:{} is equal with" + + " olapTable.getEnableMowLightDelete():{}", + enableMowLightDelete, + olapTable.getEnableMowLightDelete()); + return; + } + if (!olapTable.getEnableUniqueKeyMergeOnWrite()) { + throw new UserException("enable_mow_light_delete property is " + + "not supported for unique merge-on-read table"); + } + partitions.addAll(olapTable.getPartitions()); + } finally { + olapTable.readUnlock(); + } + param.enableMowLightDelete = enableMowLightDelete; + param.type = UpdatePartitionMetaParam.TabletMetaType.ENABLE_MOW_LIGHT_DELETE; } else { LOG.warn("invalid properties:{}", properties); throw new UserException("invalid properties"); @@ -323,6 +347,7 @@ public class CloudSchemaChangeHandler extends SchemaChangeHandler { TIME_SERIES_COMPACTION_EMPTY_ROWSETS_THRESHOLD, TIME_SERIES_COMPACTION_LEVEL_THRESHOLD, DISABLE_AUTO_COMPACTION, + ENABLE_MOW_LIGHT_DELETE, } TabletMetaType type; @@ -338,6 +363,7 @@ public class CloudSchemaChangeHandler extends SchemaChangeHandler { long timeSeriesCompactionEmptyRowsetsThreshold = 0; long timeSeriesCompactionLevelThreshold = 0; boolean disableAutoCompaction = false; + boolean enableMowLightDelete = false; } public void updateCloudPartitionMeta(Database db, @@ -412,6 +438,11 @@ public class CloudSchemaChangeHandler extends SchemaChangeHandler { infoBuilder.setDisableAutoCompaction( param.disableAutoCompaction); break; + case ENABLE_MOW_LIGHT_DELETE: + infoBuilder.setEnableMowLightDelete( + param.enableMowLightDelete + ); + break; default: throw new UserException("Unknown TabletMetaType"); } diff --git a/fe/fe-core/src/main/java/org/apache/doris/cloud/datasource/CloudInternalCatalog.java b/fe/fe-core/src/main/java/org/apache/doris/cloud/datasource/CloudInternalCatalog.java index 3ebc9d13808..584ed529546 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/cloud/datasource/CloudInternalCatalog.java +++ b/fe/fe-core/src/main/java/org/apache/doris/cloud/datasource/CloudInternalCatalog.java @@ -156,7 +156,7 @@ public class CloudInternalCatalog extends InternalCatalog { } Cloud.CreateTabletsRequest.Builder requestBuilder = Cloud.CreateTabletsRequest.newBuilder(); List<String> rowStoreColumns = - tbl.getTableProperty().getCopiedRowStoreColumns(); + tbl.getTableProperty().getCopiedRowStoreColumns(); for (Tablet tablet : index.getTablets()) { OlapFile.TabletMetaCloudPB.Builder builder = createTabletMetaBuilder(tbl.getId(), indexId, partitionId, tablet, tabletType, schemaHash, keysType, shortKeyColumnCount, @@ -169,7 +169,8 @@ public class CloudInternalCatalog extends InternalCatalog { tbl.getTimeSeriesCompactionEmptyRowsetsThreshold(), tbl.getTimeSeriesCompactionLevelThreshold(), tbl.disableAutoCompaction(), - tbl.getRowStoreColumnsUniqueIds(rowStoreColumns)); + tbl.getRowStoreColumnsUniqueIds(rowStoreColumns), + tbl.getEnableMowLightDelete()); requestBuilder.addTabletMetas(builder); } if (!storageVaultIdSet && ((CloudEnv) Env.getCurrentEnv()).getEnableStorageVault()) { @@ -216,7 +217,7 @@ public class CloudInternalCatalog extends InternalCatalog { Long timeSeriesCompactionGoalSizeMbytes, Long timeSeriesCompactionFileCountThreshold, Long timeSeriesCompactionTimeThresholdSeconds, Long timeSeriesCompactionEmptyRowsetsThreshold, Long timeSeriesCompactionLevelThreshold, boolean disableAutoCompaction, - List<Integer> rowStoreColumnUniqueIds) throws DdlException { + List<Integer> rowStoreColumnUniqueIds, boolean enableMowLightDelete) throws DdlException { OlapFile.TabletMetaCloudPB.Builder builder = OlapFile.TabletMetaCloudPB.newBuilder(); builder.setTableId(tableId); builder.setIndexId(indexId); @@ -333,6 +334,7 @@ public class CloudInternalCatalog extends InternalCatalog { schemaBuilder.addAllRowStoreColumnUniqueIds(rowStoreColumnUniqueIds); } schemaBuilder.setDisableAutoCompaction(disableAutoCompaction); + schemaBuilder.setEnableMowLightDelete(enableMowLightDelete); OlapFile.TabletSchemaCloudPB schema = schemaBuilder.build(); builder.setSchema(schema); diff --git a/fe/fe-core/src/main/java/org/apache/doris/common/util/PropertyAnalyzer.java b/fe/fe-core/src/main/java/org/apache/doris/common/util/PropertyAnalyzer.java index 29ed40676b3..32e6edc14ee 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/common/util/PropertyAnalyzer.java +++ b/fe/fe-core/src/main/java/org/apache/doris/common/util/PropertyAnalyzer.java @@ -209,10 +209,10 @@ public class PropertyAnalyzer { public static final int PROPERTIES_GROUP_COMMIT_DATA_BYTES_DEFAULT_VALUE = Config.group_commit_data_bytes_default_value; - public static final String PROPERTIES_ENABLE_MOW_DELETE_ON_DELETE_PREDICATE = - "enable_mow_delete_on_delete_predicate"; - public static final boolean PROPERTIES_ENABLE_MOW_DELETE_ON_DELETE_PREDICATE_DEFAULT_VALUE - = Config.enable_mow_delete_on_predicate; + public static final String PROPERTIES_ENABLE_MOW_LIGHT_DELETE = + "enable_mow_light_delete"; + public static final boolean PROPERTIES_ENABLE_MOW_LIGHT_DELETE_DEFAULT_VALUE + = Config.enable_mow_light_delete; // compaction policy public static final String SIZE_BASED_COMPACTION_POLICY = "size_based"; @@ -1423,18 +1423,18 @@ public class PropertyAnalyzer { if (properties == null || properties.isEmpty()) { return false; } - String value = properties.get(PropertyAnalyzer.PROPERTIES_ENABLE_MOW_DELETE_ON_DELETE_PREDICATE); + String value = properties.get(PropertyAnalyzer.PROPERTIES_ENABLE_MOW_LIGHT_DELETE); if (value == null) { return false; } - properties.remove(PropertyAnalyzer.PROPERTIES_ENABLE_MOW_DELETE_ON_DELETE_PREDICATE); + properties.remove(PropertyAnalyzer.PROPERTIES_ENABLE_MOW_LIGHT_DELETE); if (value.equals("true")) { return true; } else if (value.equals("false")) { return false; } throw new AnalysisException( - PropertyAnalyzer.PROPERTIES_ENABLE_MOW_DELETE_ON_DELETE_PREDICATE + " must be `true` or `false`"); + PropertyAnalyzer.PROPERTIES_ENABLE_MOW_LIGHT_DELETE + " must be `true` or `false`"); } /** diff --git a/fe/fe-core/src/main/java/org/apache/doris/datasource/InternalCatalog.java b/fe/fe-core/src/main/java/org/apache/doris/datasource/InternalCatalog.java index b6369a77aab..ea9d8e7610f 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/datasource/InternalCatalog.java +++ b/fe/fe-core/src/main/java/org/apache/doris/datasource/InternalCatalog.java @@ -2458,18 +2458,16 @@ public class InternalCatalog implements CatalogIf<Database> { olapTable.setEnableUniqueKeyMergeOnWrite(enableUniqueKeyMergeOnWrite); boolean enableDeleteOnDeletePredicate = false; - if (keysType == KeysType.UNIQUE_KEYS) { - try { - enableDeleteOnDeletePredicate = PropertyAnalyzer.analyzeEnableDeleteOnDeletePredicate(properties); - } catch (AnalysisException e) { - throw new DdlException(e.getMessage()); - } - if (enableDeleteOnDeletePredicate && !enableUniqueKeyMergeOnWrite) { - throw new DdlException(PropertyAnalyzer.PROPERTIES_ENABLE_MOW_DELETE_ON_DELETE_PREDICATE - + " property is not supported for unique merge-on-read table"); - } + try { + enableDeleteOnDeletePredicate = PropertyAnalyzer.analyzeEnableDeleteOnDeletePredicate(properties); + } catch (AnalysisException e) { + throw new DdlException(e.getMessage()); + } + if (enableDeleteOnDeletePredicate && !enableUniqueKeyMergeOnWrite) { + throw new DdlException(PropertyAnalyzer.PROPERTIES_ENABLE_MOW_LIGHT_DELETE + + " property is only supported for unique merge-on-write table"); } - olapTable.setEnableDeleteOnDeletePredicate(enableDeleteOnDeletePredicate); + olapTable.setEnableMowLightDelete(enableDeleteOnDeletePredicate); boolean enableSingleReplicaCompaction = false; try { diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/DeleteFromCommand.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/DeleteFromCommand.java index cbfa94be050..fe5552fed65 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/DeleteFromCommand.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/DeleteFromCommand.java @@ -167,7 +167,7 @@ public class DeleteFromCommand extends Command implements ForwardWithSync, Expla } if (olapTable.getKeysType() == KeysType.UNIQUE_KEYS && olapTable.getEnableUniqueKeyMergeOnWrite() - && !olapTable.getEnableDeleteOnDeletePredicate()) { + && !olapTable.getEnableMowLightDelete()) { new DeleteFromUsingCommand(nameParts, tableAlias, isTempPart, partitions, logicalQuery, Optional.empty()).run(ctx, executor); return; diff --git a/fe/fe-core/src/test/java/org/apache/doris/analysis/CreateTableAsSelectStmtTest.java b/fe/fe-core/src/test/java/org/apache/doris/analysis/CreateTableAsSelectStmtTest.java index d3c7bdf95a5..5e6c53b18ad 100644 --- a/fe/fe-core/src/test/java/org/apache/doris/analysis/CreateTableAsSelectStmtTest.java +++ b/fe/fe-core/src/test/java/org/apache/doris/analysis/CreateTableAsSelectStmtTest.java @@ -578,7 +578,7 @@ public class CreateTableAsSelectStmtTest extends TestWithFeService { + "\"enable_single_replica_compaction\" = \"false\",\n" + "\"group_commit_interval_ms\" = \"10000\",\n" + "\"group_commit_data_bytes\" = \"134217728\",\n" - + "\"enable_mow_delete_on_delete_predicate\" = \"false\"\n" + + "\"enable_mow_light_delete\" = \"false\"\n" + ");", showResultSet.getResultRows().get(0).get(1)); } diff --git a/gensrc/proto/cloud.proto b/gensrc/proto/cloud.proto index ab69deaa212..5179ea52a9e 100644 --- a/gensrc/proto/cloud.proto +++ b/gensrc/proto/cloud.proto @@ -497,6 +497,7 @@ message TabletMetaInfoPB { // For update tablet meta optional int64 time_series_compaction_empty_rowsets_threshold = 11; optional int64 time_series_compaction_level_threshold = 12; optional bool disable_auto_compaction = 13; + optional bool enable_mow_light_delete = 14; } message TabletCompactionJobPB { diff --git a/gensrc/proto/olap_file.proto b/gensrc/proto/olap_file.proto index 1f8f88801be..f2fbf09122d 100644 --- a/gensrc/proto/olap_file.proto +++ b/gensrc/proto/olap_file.proto @@ -411,6 +411,7 @@ message TabletSchemaCloudPB { optional InvertedIndexStorageFormatPB inverted_index_storage_format = 25 [default=V1]; // column unique ids for row store columns repeated int32 row_store_column_unique_ids = 26; + optional bool enable_mow_light_delete = 27 [default=false]; optional bool is_dynamic_schema = 100 [default=false]; } diff --git a/regression-test/data/query_p0/system/test_table_options.out b/regression-test/data/query_p0/system/test_table_options.out index 71b7de92f83..974c3bc2c7e 100644 --- a/regression-test/data/query_p0/system/test_table_options.out +++ b/regression-test/data/query_p0/system/test_table_options.out @@ -1,9 +1,9 @@ -- This file is automatically generated. You should know what you did if you want to edit this -- !select -- -aggregate_table internal test_table_options_db AGG user_id,date,city,age,sex user_id HASH 1 1 {"min_load_replica_num":"-1","data_sort.col_num":"5","group_commit_interval_ms":"10000","data_sort.sort_type":"LEXICAL","is_being_synced":"false","binlog.enable":"false","binlog.ttl_seconds":"86400","inverted_index_storage_format":"V2","time_series_compaction_empty_rowsets_threshold":"5","default.replication_allocation":"tag.location.default: 1","time_series_compaction_level_threshold":"1","time [...] -duplicate_table internal test_table_options_db DUP timestamp,type,error_code type HASH 1 1 {"min_load_replica_num":"-1","data_sort.col_num":"3","group_commit_interval_ms":"10000","data_sort.sort_type":"LEXICAL","is_being_synced":"false","binlog.enable":"false","binlog.ttl_seconds":"86400","inverted_index_storage_format":"V2","time_series_compaction_empty_rowsets_threshold":"5","default.replication_allocation":"tag.location.default: 1","time_series_compaction_level_threshold":"1","time_se [...] -listtable internal test_table_options_db AGG user_id,date,timestamp,city,age,sex user_id HASH 16 3 {"min_load_replica_num":"-1","data_sort.col_num":"6","group_commit_interval_ms":"10000","data_sort.sort_type":"LEXICAL","is_being_synced":"false","binlog.enable":"false","binlog.ttl_seconds":"86400","inverted_index_storage_format":"V2","time_series_compaction_empty_rowsets_threshold":"5","default.replication_allocation":"tag.location.default: 1","time_series_compaction_level_threshold":"1", [...] -randomtable internal test_table_options_db DUP user_id,date,timestamp RANDOM RANDOM 16 1 {"min_load_replica_num":"-1","data_sort.col_num":"3","group_commit_interval_ms":"10000","data_sort.sort_type":"LEXICAL","is_being_synced":"false","binlog.enable":"false","binlog.ttl_seconds":"86400","inverted_index_storage_format":"V2","time_series_compaction_empty_rowsets_threshold":"5","default.replication_allocation":"tag.location.default: 1","time_series_compaction_level_threshold":"1","time_seri [...] -rangetable internal test_table_options_db AGG user_id,date,timestamp,city,age,sex user_id HASH 8 3 {"min_load_replica_num":"-1","data_sort.col_num":"6","group_commit_interval_ms":"10000","data_sort.sort_type":"LEXICAL","is_being_synced":"false","binlog.enable":"false","binlog.ttl_seconds":"86400","inverted_index_storage_format":"V2","time_series_compaction_empty_rowsets_threshold":"5","default.replication_allocation":"tag.location.default: 1","time_series_compaction_level_threshold":"1", [...] -unique_table internal test_table_options_db UNI user_id,username user_id HASH 1 1 {"min_load_replica_num":"-1","data_sort.col_num":"2","group_commit_interval_ms":"10000","data_sort.sort_type":"LEXICAL","is_being_synced":"false","binlog.enable":"false","binlog.ttl_seconds":"86400","inverted_index_storage_format":"V2","time_series_compaction_empty_rowsets_threshold":"5","default.replication_allocation":"tag.location.default: 1","time_series_compaction_level_threshold":"1","time_series_comp [...] +aggregate_table internal test_table_options_db AGG user_id,date,city,age,sex user_id HASH 1 1 {"min_load_replica_num":"-1","data_sort.col_num":"5","group_commit_interval_ms":"10000","data_sort.sort_type":"LEXICAL","is_being_synced":"false","binlog.enable":"false","enable_mow_light_delete":"false","binlog.ttl_seconds":"86400","inverted_index_storage_format":"V2","time_series_compaction_empty_rowsets_threshold":"5","default.replication_allocation":"tag.location.default: 1","time_series_com [...] +duplicate_table internal test_table_options_db DUP timestamp,type,error_code type HASH 1 1 {"min_load_replica_num":"-1","data_sort.col_num":"3","group_commit_interval_ms":"10000","data_sort.sort_type":"LEXICAL","is_being_synced":"false","binlog.enable":"false","enable_mow_light_delete":"false","binlog.ttl_seconds":"86400","inverted_index_storage_format":"V2","time_series_compaction_empty_rowsets_threshold":"5","default.replication_allocation":"tag.location.default: 1","time_series_compac [...] +listtable internal test_table_options_db AGG user_id,date,timestamp,city,age,sex user_id HASH 16 3 {"min_load_replica_num":"-1","data_sort.col_num":"6","group_commit_interval_ms":"10000","data_sort.sort_type":"LEXICAL","is_being_synced":"false","binlog.enable":"false","enable_mow_light_delete":"false","binlog.ttl_seconds":"86400","inverted_index_storage_format":"V2","time_series_compaction_empty_rowsets_threshold":"5","default.replication_allocation":"tag.location.default: 1","time_serie [...] +randomtable internal test_table_options_db DUP user_id,date,timestamp RANDOM RANDOM 16 1 {"min_load_replica_num":"-1","data_sort.col_num":"3","group_commit_interval_ms":"10000","data_sort.sort_type":"LEXICAL","is_being_synced":"false","binlog.enable":"false","enable_mow_light_delete":"false","binlog.ttl_seconds":"86400","inverted_index_storage_format":"V2","time_series_compaction_empty_rowsets_threshold":"5","default.replication_allocation":"tag.location.default: 1","time_series_compacti [...] +rangetable internal test_table_options_db AGG user_id,date,timestamp,city,age,sex user_id HASH 8 3 {"min_load_replica_num":"-1","data_sort.col_num":"6","group_commit_interval_ms":"10000","data_sort.sort_type":"LEXICAL","is_being_synced":"false","binlog.enable":"false","enable_mow_light_delete":"false","binlog.ttl_seconds":"86400","inverted_index_storage_format":"V2","time_series_compaction_empty_rowsets_threshold":"5","default.replication_allocation":"tag.location.default: 1","time_serie [...] +unique_table internal test_table_options_db UNI user_id,username user_id HASH 1 1 {"min_load_replica_num":"-1","data_sort.col_num":"2","group_commit_interval_ms":"10000","data_sort.sort_type":"LEXICAL","is_being_synced":"false","binlog.enable":"false","enable_mow_light_delete":"false","binlog.ttl_seconds":"86400","inverted_index_storage_format":"V2","time_series_compaction_empty_rowsets_threshold":"5","default.replication_allocation":"tag.location.default: 1","time_series_compaction_leve [...] diff --git a/regression-test/suites/unique_with_mow_p0/partial_update/test_new_partial_update_delete.groovy b/regression-test/suites/unique_with_mow_p0/partial_update/test_new_partial_update_delete.groovy index 015af68b9aa..bcd8d5f2842 100644 --- a/regression-test/suites/unique_with_mow_p0/partial_update/test_new_partial_update_delete.groovy +++ b/regression-test/suites/unique_with_mow_p0/partial_update/test_new_partial_update_delete.groovy @@ -43,12 +43,12 @@ suite('test_new_partial_update_delete') { PROPERTIES ( "disable_auto_compaction" = "true", "enable_unique_key_merge_on_write" = "false", - "enable_mow_delete_on_delete_predicate" = "true", + "enable_mow_light_delete" = "true", "replication_num" = "1", "store_row_column" = "${use_row_store}"); """ } catch (Exception e) { log.info(e.getMessage()) - assertTrue(e.getMessage().contains('enable_mow_delete_on_delete_predicate property is not supported for unique merge-on-read table')) + assertTrue(e.getMessage().contains('enable_mow_light_delete property is only supported for unique merge-on-write table')) } try { @@ -67,10 +67,10 @@ suite('test_new_partial_update_delete') { "enable_unique_key_merge_on_write" = "false", "replication_num" = "1", "store_row_column" = "${use_row_store}"); """ - sql """alter table ${tableMorName2} set ("enable_mow_delete_on_delete_predicate"="true")""" + sql """alter table ${tableMorName2} set ("enable_mow_light_delete"="true")""" } catch (Exception e) { log.info(e.getMessage()) - assertTrue(e.getMessage().contains('enable_mow_delete_on_delete_predicate property is not supported for unique merge-on-read table')) + assertTrue(e.getMessage().contains('enable_mow_light_delete property is only supported for unique merge-on-write table')) } def tableName1 = "test_new_partial_update_delete1" @@ -89,7 +89,7 @@ suite('test_new_partial_update_delete') { "store_row_column" = "${use_row_store}"); """ def output1 = sql "show create table ${tableName1}" - assertTrue output1[0][1].contains("\"enable_mow_delete_on_delete_predicate\" = \"false\""); + assertTrue output1[0][1].contains("\"enable_mow_light_delete\" = \"false\""); sql "insert into ${tableName1} values(1,1,1,1,1)" // 1,1,1,1,1 qt_sql1 "select * from ${tableName1} order by k1;" @@ -108,11 +108,11 @@ suite('test_new_partial_update_delete') { - sql """alter table ${tableName1} set ("enable_mow_delete_on_delete_predicate"="true") """ + sql """alter table ${tableName1} set ("enable_mow_light_delete"="true") """ sql "set enable_unique_key_partial_update=false;" sql "set enable_insert_strict=true;" def output2 = sql "show create table ${tableName1}" - assertTrue output2[0][1].contains("\"enable_mow_delete_on_delete_predicate\" = \"true\""); + assertTrue output2[0][1].contains("\"enable_mow_light_delete\" = \"true\""); sql "insert into ${tableName1} values(2,2,2,2,2)" // 1,2,NULL,NULL,NULL // 2,2,2,2,2 @@ -156,12 +156,12 @@ suite('test_new_partial_update_delete') { PROPERTIES ( "disable_auto_compaction" = "true", "enable_unique_key_merge_on_write" = "false", - "enable_mow_delete_on_delete_predicate" = "true", + "enable_mow_light_delete" = "true", "replication_num" = "1", "store_row_column" = "${use_row_store}"); """ } catch (Exception e) { log.info(e.getMessage()) - assertTrue(e.getMessage().contains('enable_mow_delete_on_delete_predicate property is not supported for unique merge-on-read table')) + assertTrue(e.getMessage().contains('enable_mow_light_delete property is only supported for unique merge-on-write table')) } try { @@ -180,10 +180,10 @@ suite('test_new_partial_update_delete') { "enable_unique_key_merge_on_write" = "false", "replication_num" = "1", "store_row_column" = "${use_row_store}"); """ - sql """alter table ${tableMorName4} set ("enable_mow_delete_on_delete_predicate"="true")""" + sql """alter table ${tableMorName4} set ("enable_mow_light_delete"="true")""" } catch (Exception e) { log.info(e.getMessage()) - assertTrue(e.getMessage().contains('enable_mow_delete_on_delete_predicate property is not supported for unique merge-on-read table')) + assertTrue(e.getMessage().contains('enable_mow_light_delete property is only supported for unique merge-on-write table')) } sql "set enable_nereids_planner=false" def tableName2 = "test_new_partial_update_delete2" @@ -202,7 +202,7 @@ suite('test_new_partial_update_delete') { "store_row_column" = "${use_row_store}"); """ def output3 = sql "show create table ${tableName2}" - assertTrue output3[0][1].contains("\"enable_mow_delete_on_delete_predicate\" = \"false\""); + assertTrue output3[0][1].contains("\"enable_mow_light_delete\" = \"false\""); sql "insert into ${tableName2} values(1,1,1,1,1)" // 1,1,1,1,1 qt_sql21 "select * from ${tableName2} order by k1;" @@ -221,11 +221,11 @@ suite('test_new_partial_update_delete') { - sql """alter table ${tableName2} set ("enable_mow_delete_on_delete_predicate"="true") """ + sql """alter table ${tableName2} set ("enable_mow_light_delete"="true") """ sql "set enable_unique_key_partial_update=false;" sql "set enable_insert_strict=true;" def output4 = sql "show create table ${tableName2}" - assertTrue output4[0][1].contains("\"enable_mow_delete_on_delete_predicate\" = \"true\""); + assertTrue output4[0][1].contains("\"enable_mow_light_delete\" = \"true\""); sql "insert into ${tableName2} values(2,2,2,2,2)" // 1,2,NULL,NULL,NULL // 2,2,2,2,2 @@ -253,4 +253,47 @@ suite('test_new_partial_update_delete') { sql "drop table if exists ${tableName2};" } } + + connect(user = context.config.jdbcUser, password = context.config.jdbcPassword, url = context.config.jdbcUrl) { + sql "use ${db};" + try { + def tableAggName = "test_new_partial_update_agg_delete" + sql "DROP TABLE IF EXISTS ${tableAggName};" + sql """ CREATE TABLE IF NOT EXISTS ${tableAggName} ( + `k1` int NOT NULL, + `c1` int replace, + `c2` int replace, + `c3` int replace, + `c4` int replace + )AGGREGATE KEY(k1) + DISTRIBUTED BY HASH(k1) BUCKETS 1 + PROPERTIES ( + "disable_auto_compaction" = "true", + "enable_mow_light_delete" = "true", + "replication_num" = "1"); """ + } catch (Exception e) { + log.info(e.getMessage()) + assertTrue(e.getMessage().contains('enable_mow_light_delete property is only supported for unique merge-on-write table')) + } + + try { + def tableDupName = "test_new_partial_update_dup_delete" + sql "DROP TABLE IF EXISTS ${tableDupName};" + sql """ CREATE TABLE IF NOT EXISTS ${tableDupName} ( + `k1` int NOT NULL, + `c1` int, + `c2` int, + `c3` int, + `c4` int + )DUPLICATE KEY(k1) + DISTRIBUTED BY HASH(k1) BUCKETS 1 + PROPERTIES ( + "disable_auto_compaction" = "true", + "enable_mow_light_delete" = "true", + "replication_num" = "1"); """ + } catch (Exception e) { + log.info(e.getMessage()) + assertTrue(e.getMessage().contains('enable_mow_light_delete property is only supported for unique merge-on-write table')) + } + } } --------------------------------------------------------------------- To unsubscribe, e-mail: commits-unsubscr...@doris.apache.org For additional commands, e-mail: commits-h...@doris.apache.org