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 3d9031a7098382..9a703903cf00ae 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 @@ -2704,7 +2704,7 @@ private void cancelIndexJob(CancelAlterTableStmt cancelAlterTableStmt) throws Dd /** * Returns true if the index already exists, there is no need to create the job to add the index. - * Otherwise return false, there is need to create a job to add the index. + * Otherwise, return false, there is need to create a job to add the index. */ private boolean processAddIndex(CreateIndexClause alterClause, OlapTable olapTable, List newIndexes) throws UserException { @@ -2718,23 +2718,11 @@ private boolean processAddIndex(CreateIndexClause alterClause, OlapTable olapTab Set newColset = Sets.newTreeSet(String.CASE_INSENSITIVE_ORDER); newColset.addAll(indexDef.getColumns()); Set existedIndexIdSet = Sets.newHashSet(); - for (Index existedIdx : existedIndexes) { - if (existedIdx.getIndexName().equalsIgnoreCase(indexDef.getIndexName())) { - if (indexDef.isSetIfNotExists()) { - LOG.info("create index[{}] which already exists on table[{}]", indexDef.getIndexName(), - olapTable.getName()); - return true; - } - throw new DdlException("index `" + indexDef.getIndexName() + "` already exist."); - } - Set existedIdxColSet = Sets.newTreeSet(String.CASE_INSENSITIVE_ORDER); - existedIdxColSet.addAll(existedIdx.getColumns()); - if (existedIdx.getIndexType() == indexDef.getIndexType() && newColset.equals(existedIdxColSet)) { - throw new DdlException( - indexDef.getIndexType() + " index for columns (" + String.join(",", indexDef.getColumns()) - + " ) already exist."); - } - existedIndexIdSet.add(existedIdx.getIndexId()); + if (checkDuplicateIndexes(existedIndexes, indexDef, newColset, existedIndexIdSet, olapTable)) { + return true; + } + if (checkDuplicateIndexes(newIndexes, indexDef, newColset, existedIndexIdSet, olapTable)) { + return true; } // The restored olap table may not reset the index id, which comes from the upstream, @@ -2770,6 +2758,29 @@ private boolean processAddIndex(CreateIndexClause alterClause, OlapTable olapTab return false; } + private boolean checkDuplicateIndexes(List indexes, IndexDef indexDef, Set newColset, + Set existedIndexIdSet, OlapTable olapTable) throws DdlException { + for (Index index : indexes) { + if (index.getIndexName().equalsIgnoreCase(indexDef.getIndexName())) { + if (indexDef.isSetIfNotExists()) { + LOG.info("create index[{}] which already exists on table[{}]", indexDef.getIndexName(), + olapTable.getName()); + return true; + } + throw new DdlException("index `" + indexDef.getIndexName() + "` already exist."); + } + Set existedIdxColSet = Sets.newTreeSet(String.CASE_INSENSITIVE_ORDER); + existedIdxColSet.addAll(index.getColumns()); + if (index.getIndexType() == indexDef.getIndexType() && newColset.equals(existedIdxColSet)) { + throw new DdlException( + indexDef.getIndexType() + " index for columns (" + String.join(",", indexDef.getColumns()) + + ") already exist."); + } + existedIndexIdSet.add(index.getIndexId()); + } + return false; + } + /** * Returns true if the index does not exist, there is no need to create the job to drop the index. * Otherwise return false, there is need to create a job to drop the index. diff --git a/fe/fe-core/src/test/java/org/apache/doris/alter/SchemaChangeHandlerTest.java b/fe/fe-core/src/test/java/org/apache/doris/alter/SchemaChangeHandlerTest.java index 649d7e4facb54f..8f7e2d6b2f6553 100644 --- a/fe/fe-core/src/test/java/org/apache/doris/alter/SchemaChangeHandlerTest.java +++ b/fe/fe-core/src/test/java/org/apache/doris/alter/SchemaChangeHandlerTest.java @@ -556,4 +556,40 @@ public void testDupAddOrDropInvertedIndex() throws Exception { tbl.readUnlock(); } } + + @Test + public void testAddDuplicateInvertedIndexException() throws Exception { + + LOG.info("dbName: {}", Env.getCurrentInternalCatalog().getDbNames()); + + Database db = Env.getCurrentInternalCatalog().getDbOrMetaException("test"); + OlapTable tbl = (OlapTable) db.getTableOrMetaException("sc_dup", Table.TableType.OLAP); + tbl.readLock(); + try { + Assertions.assertNotNull(tbl); + Assertions.assertEquals("Doris", tbl.getEngine()); + Assertions.assertEquals(0, tbl.getIndexes().size()); + } finally { + tbl.readUnlock(); + } + + String addInvertedIndexStmtStr = "alter table test.sc_dup add index idx_error_msg(error_msg), " + + "add index idx_error_msg1(error_msg)"; + AlterTableStmt addInvertedIndexStmt = (AlterTableStmt) parseAndAnalyzeStmt(addInvertedIndexStmtStr); + try { + Env.getCurrentEnv().getAlterInstance().processAlterTable(addInvertedIndexStmt); + } catch (Exception e) { + // Verify the error message contains relevant info + Assertions.assertTrue(e.getMessage().contains("INVERTED index for columns (error_msg) already exist")); + } + addInvertedIndexStmtStr = "alter table test.sc_dup add index idx_error_msg(error_msg), " + + "add index idx_error_msg(error_msg)"; + addInvertedIndexStmt = (AlterTableStmt) parseAndAnalyzeStmt(addInvertedIndexStmtStr); + try { + Env.getCurrentEnv().getAlterInstance().processAlterTable(addInvertedIndexStmt); + } catch (Exception e) { + // Verify the error message contains relevant info + Assertions.assertTrue(e.getMessage().contains("index `idx_error_msg` already exist.")); + } + } }